Reputation: 1256
I'm new to all of this thing, and so please excuse me if i kinda did something stupid here. Treat me and explain to me as if i'm a total noob would be helpful.
I have a simple function written in python, filename a.pyx
:-
#!/usr/bin/env python
import os
import sys
def get_syspath():
ret = sys.path
print "Syspath:{}".format(ret)
return ret
I want it to be able to be used by tcl.
I read thru the cython page, and followed.
I ran this:-
cython -o a.c a.pyx
I then ran this command to generate the object file a.o
:-
gcc -fpic -c a.c -I/usr/local/include -I/tools/share/python/2.7.1/linux64/include/python2.7
And then ran this to generate the so file a.so
:-
gcc -shared a.o -o a.so
when i load it from a tclsh, it failed.
$tclsh
% load ./a.so
couldn't load file "./a.so": ./a.so: undefined symbol: PyExc_RuntimeError
Am i taking the correct path here? If not, can please explain to me what went wrong, and what should I be doing?
Thanks in advance.
Upvotes: 1
Views: 188
Reputation: 7237
Maybe have a look at tclpython
or libtclpy
.
Both allow calling Python code from Tcl.
But if you wanted to wrap things in a nicer way, e.g. have nicer already wrapped APIs, maybe you should also look at Elmer, which seems to aim at the task your attempting.
Upvotes: 1
Reputation: 137567
The object code needs to be linked to the libraries it depends on when you're building the loadable library. This means adding appropriate -l...
options and possibly some -L...
options as well. I'm guessing that the option will be something like -lpython27
or something like that (which links to a libpython27.so
somewhere on your library search path; the library search path is modified with the -L...
options), but I don't know. Paths will depend a lot on exactly how your system is set up and experimentation is likely required on your half.
It still probably won't work as a loadable library in Tcl. Tcl expects there to be a library initialisation function (in your case, it will look for A_Init
) that takes a Tcl_Interp*
as its only argument so that the library can install the commands it defines into the Tcl interpreter context. I would be astonished if Python made such a thing by default. It's not failing with that for you yet because the failures are still happening during the internal dlopen()
call and not the dlsym()
call, but I can confidently predict that you'll still face them.
The easiest way to “integrate” that sort of functionality is by running the command in a subprocess.
Here's the Python code you might use:
import os
import sys
print sys.path
And here's the Tcl code to use it:
set syspath [exec python /path/to/yourcode.py]
# If it is in the same directory as this script, use this:
#set syspath [exec python [file join [file dirname [info script]] yourcode.py]]
It's not the most efficient way, but it's super-easy to make it work since you don't have to solve the compilation and linking of the two languages. It's programmer-efficient…
Upvotes: 2