Thanks Michael
I should have mentioned that I used -lpython2.7 on both Mint and
Debian.
Hopefully this is just a Mint problem or my mistake now.
On 7/18/2013 5:06 AM, Michael Anderson wrote:
On 07/17/2013 09:28 PM, Patrick
wrote:
Does anyone have a fairly new install of Mint 15 to double check my
findings? Can anyone run this on Ubuntu to see if it's introduced upstream?
On Ubuntu 12.04, it compiled fine, but I'm running Python 2.7
$ cobc -x cobpy.cob -lpython2.7
$ ./cobpy
link cobpy with -lpython2.6
libcob: Cannot find module 'Py_Finalize'
So I commented-out the call to Py_Finalize...
$ cobc -x cobpy.cob -lpython2.7
$ ./cobpy
link cobpy with -lpython2.6
$
So, it seems like 'Py_Initialize' was found by the coblib
runtime?, but a Call exception occurred and then Py_Finalize is
not found.
$ ldd cobpy
linux-gate.so.1 => (0xb7773000)
libcob.so.1 => /usr/local/lib/libcob.so.1 (0xb7721000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7578000)
libm.so.6 => /lib/i386-linux-gnu/libm.so.6 (0xb754b000)
libgmp.so.10 => /usr/lib/i386-linux-gnu/libgmp.so.10
(0xb74cc000)
libncurses.so.5 => /lib/i386-linux-gnu/libncurses.so.5
(0xb74aa000)
libtinfo.so.5 => /lib/i386-linux-gnu/libtinfo.so.5
(0xb748b000)
libdb-5.1.so => /usr/lib/i386-linux-gnu/libdb-5.1.so
(0xb7303000)
libdl.so.2 => /lib/i386-linux-gnu/libdl.so.2 (0xb72fd000)
/lib/ld-linux.so.2 (0xb7774000)
libpthread.so.0 => /lib/i386-linux-gnu/libpthread.so.0
(0xb72e2000)
Maybe I'm doing something wrong. I've only been developing
software in the Unix env since 2008.
Prior to 2008, MPE/iX was my OS of choice.
So whats going on, look at readelf.......
$ readelf -a /usr/lib/libpython2.7.so|grep Py_Initialize
941: 000a4cc0 2615 FUNC GLOBAL DEFAULT 11
Py_InitializeEx
1517: 000a5700 32 FUNC GLOBAL DEFAULT 11
Py_Initialize
$ readelf -a /usr/lib/libpython2.7.so|grep Py_Finalize
1267: 00069750 600 FUNC GLOBAL DEFAULT 11
Py_Finalize
So Py_Finalize is in their, what the heck? I don't know, there
maybe a bug in the OC "CALL" statement, but for me, there is
always a work around.
Lets try it in C.
$ more gccpy.c
#include <Python.h>
int
main(int argc, char *argv[])
{
Py_Initialize();
PyRun_SimpleString("from time import time,ctime\n"
"print 'Today is',ctime(time())\n");
Py_Finalize();
return 0;
}
$ cobc -x -I/usr/include/python2.7 gccpy.c -lpython2.7
$ ./gccpy
Today is Wed Jul 18 02:40:35 2013
$
It works! and notice I used cobc to compile it!
I've had similar issues with Tcl... and I've done lots of
Cobol/Tcl running in production environments since 2008.
The purpose behind embedded scripts, Python, Tcl, Guile, or
similar, is for me, portability, not being tied to specific
compiler features.
Or to modify key features of your software without recompiling....
just change your scripts. there are pros an cons.
Maybe a work-around, but I get better (more reliable) results
using my own (Cobol Friendly) C wrapper library to call the C
functions that were not originally designed to be called from
Cobol, not calling these directly from Cobol, but instead called
from a library that was designed to be called by Cobol.
That said, dynamic linking should work correctly.
Maybe a bug in coblib, and if so, even if it gets fixed I'll still
prefer using a dynamic wrapper library to do these types of
things.
Example:
This may help with embedded Python also.
in C:
extern void TCLEVAL (Tcl_Interp **tclhandle, char *script, int
*result)
{
*result = Tcl_Eval(*tclhandle, script);
}
Then in Cobol:
Move low-values To TCL-BUFFER.
String "some Tcl statement" delimited by
size into TCL-BUFFER.
CALL "TCLEVAL" USING TCL-INTR TCL-BUFFER TCL-RESULT.
BTW: jim looks like a nice minimal Tcl library, which is a
good thing for packaging your software.
However, in development mode on Ubuntu, I just use the standard
Tcllib that comes with Ubuntu.
"sudo apt-get install tcl8.5-dev",
then add any non-standard packages like pdf4tcl.
In my C library "cobtcl" I have (Cobol Friendly) STARTTCL,
STOPTCL, TCLEVAL, TCLSETVAR, TCLGETVAR, and TCLEVALFILE.
EXAMPLE of the problem, first without cobtcl library, calling the
Tcl* functions directly from OpenCobol:
$ cobc -x -free -ffunctions-all -I/usr/include/tcl8.5
-ltcl8.5 getlotto.cob
$ ./getlotto
libcob: Cannot find module 'Tcl_FindExecutable'
$
I have successfully compiled and linked same as above, and it ran
fine on other Linux machines.
But on some machines it does not work, "can't find module" and I
have no idea why!
$ ldd getlotto
linux-gate.so.1 => (0xb77e0000)
libcob.so.1 => /usr/local/lib/libcob.so.1
(0xb778e000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6
(0xb75e5000)
libm.so.6 => /lib/i386-linux-gnu/libm.so.6
(0xb75b8000)
libgmp.so.10 =>
/usr/lib/i386-linux-gnu/libgmp.so.10 (0xb7539000)
libncurses.so.5 =>
/lib/i386-linux-gnu/libncurses.so.5 (0xb7517000)
libtinfo.so.5 =>
/lib/i386-linux-gnu/libtinfo.so.5 (0xb74f8000)
libdb-5.1.so =>
/usr/lib/i386-linux-gnu/libdb-5.1.so (0xb7370000)
libdl.so.2 => /lib/i386-linux-gnu/libdl.so.2
(0xb736a000)
/lib/ld-linux.so.2 (0xb77e1000)
libpthread.so.0 =>
/lib/i386-linux-gnu/libpthread.so.0 (0xb734f000)
I know that Tcl_FindExecutable is in libtcl8.5.so, and -ltcl8.5 is
correct, but 'ldd' says that getlotto is not even looking for
libtcl8.5.so ..
and therefore coblib does not find it, can't find it.
However, if statically linked, then it does find it.
Not wanting to compile the entire libtcl into my cobol program,
I instead write a small C wrapper, cobtcl.c, statically linking
cobtcl.o seems to make it work.
This makes sense too me, because coblib is not calling the
dynamically linked functions, clib is calling those.
coblib is only calling the statically liked functions in cobtcl.o
So I modified getlotto.cob to call my cobtcl C functions,
STARTTCL, and so on... saved it as newgetlotto.cob
$ cobc -c -I/usr/include/tcl8.5 cobtcl.c
$ cobc -x -ffunctions-all -free -ltcl8.5 newgetlotto.cob
cobtcl.o
$ ./newgetlotto
Most recent drawing: Lotto
Texas,7,17,2013,40,8,3,12,15,25
$
$ ldd newgetlotto
linux-gate.so.1 => (0xb7749000)
libcob.so.1 => /usr/local/lib/libcob.so.1
(0xb76f7000)
libtcl8.5.so.0 =>
/usr/lib/libtcl8.5.so.0 (0xb75dd000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6
(0xb7433000)
libm.so.6 => /lib/i386-linux-gnu/libm.so.6
(0xb7407000)
libgmp.so.10 =>
/usr/lib/i386-linux-gnu/libgmp.so.10 (0xb7388000)
libncurses.so.5 =>
/lib/i386-linux-gnu/libncurses.so.5 (0xb7366000)
libtinfo.so.5 => /lib/i386-linux-gnu/libtinfo.so.5
(0xb7347000)
libdb-5.1.so =>
/usr/lib/i386-linux-gnu/libdb-5.1.so (0xb71be000)
libdl.so.2 => /lib/i386-linux-gnu/libdl.so.2
(0xb71b9000)
libpthread.so.0 =>
/lib/i386-linux-gnu/libpthread.so.0 (0xb719e000)
/lib/ld-linux.so.2 (0xb774a000)
Now it works!
more rambling's..............
BTW: Patrick, if you want a complete copy these examples cobtcl.c,
just email me.. that goes for anyone.
The lotto program is just a dumb example that anyone can follow,
I use Tcl for all kinds misc functions, like access to sql data,
getting resources from web servers, status of files, creating
PDF's, and much more.
Another example encrypt/decrypt a password.
These examples are AcuCobol, but the same exact source works with
OpenCOBOL.
In OpenCobol I would have used the trim function instead of
"delimited by size" and "delimited by space"
Here we Execute two pre-written Tcl functions known as 'procs',
EncryptData, and DecryptData.
So yes, you can develop all your Tcl procs, store them in one
file, ea. myprocs.tcl.
Then load all these procs into the interpreter using TCLEVALFILE
after calling STARTTCL.
Then anytime within your cobol app, you can execute a specific
proc, and pass parms using TCLEVAL.
*>---------------------------------------------------------
Encrypt-string.
Move Spaces To Encrypted-string.
Perform Set-Encryption-Key.
Move LOW-VALUES TO TCL-BUFFER.
Move 0 To TCL-RESULT.
*> =========
*> EncryptData takes two parms, a string, and a length.
*> if you were in the tclsh shell, the command would
look like so:
*> set cipher [EncryptData mypasswd 8]
*> now the var 'cipher' contains the encrypted value of
mypasswd
*> =========
String "set cipher [EncryptData " Delimited By Size
Cleartext-String Delimited By " "
" 8]" delimited by size
into TCL-BUFFER.
CALL "TCLEVAL" USING TCL-INTR TCL-BUFFER TCL-RESULT.
MOVE LOW-VALUES TO TCL-VARNAME
STRING "cipher" DELIMITED BY SIZE INTO TCL-VARNAME.
MOVE SPACES TO TCL-BUFFER.
CALL "TCLGETVAR" USING TCL-INTR TCL-VARNAME
TCL-BUFFER.
Move Spaces To Encrypted-string.
String TCL-BUFFER delimited by x"00" into
Encrypted-string.
*>---------------------------------------------------------
Decrypt-String.
Perform Set-Encryption-Key.
Move LOW-VALUES TO TCL-BUFFER.
MOVE LOW-VALUES TO TCL-VARNAME
Move 0 To TCL-RESULT.
Move Spaces To ClearText-String.
String "set CLEARTEXT [DecryptData " delimited by
size
Encrypted-string delimited by " "
" 8]" delimited by size
into TCL-BUFFER.
CALL "TCLEVAL" USING TCL-INTR TCL-BUFFER TCL-RESULT.
STRING "CLEARTEXT" DELIMITED BY SIZE INTO
TCL-VARNAME
MOVE SPACES TO TCL-BUFFER.
CALL "TCLGETVAR" USING TCL-INTR TCL-VARNAME
TCL-BUFFER.
String TCL-BUFFER delimited by x"00" into
ClearText-String.
*>---------------------------------------------------------
Set-Encryption-Key.
Move LOW-VALUES TO TCL-BUFFER.
MOVE LOW-VALUES TO TCL-VARNAME.
Move Spaces To MY-KEY.
String AUTHSESS-USER Delimited By Space
AUTHSESS-FWTYPE AUTHSESS-LOG-ON-LOC
AUTHSESS-HOME-LOC Delimited By Size
AUTHSESS-FWIP Delimited By "."
Into MY-KEY.
Inspect MY-KEY replacing all " " by "0".
String MY-KEY
Delimited By Size InTo TCL-BUFFER.
STRING "TIWAPPKEY"
Delimited By Size InTo TCL-VARNAME.
CALL "TCLSETVAR" USING TCL-INTR TCL-VARNAME TCL-BUFFER.
------------------------------------------------------------------------------
See everything from the browser to the database with AppDynamics
Get end-to-end visibility with application monitoring from AppDynamics
Isolate bottlenecks and diagnose root cause in seconds.
Start your free trial of AppDynamics Pro today!
http://pubads.g.doubleclick.net/gampad/clk?id=48808831&iu=/4140/ostg.clktrk
_______________________________________________
open-cobol-list mailing list
address@hidden
https://lists.sourceforge.net/lists/listinfo/open-cobol-list
|