2016-08-22 113 views
1

我对这件事情都很陌生,所以请原谅我,如果我在这里做了一些愚蠢的事情。对待我,并向我解释,好像我是一个总noob会有帮助。试图在tcl中支持Python代码

我用Python编写的一个简单的功能,文件名a.pyx: -

#!/usr/bin/env python 

import os 
import sys 

def get_syspath(): 
    ret = sys.path 
    print "Syspath:{}".format(ret) 
    return ret 

我希望它能够通过TCL使用。

我通过cython页面阅读,然后。

我跑了这一点: -

cython -o a.c a.pyx 

然后我跑到这个命令生成目标文件a.o: -

gcc -fpic -c a.c -I/usr/local/include -I/tools/share/python/2.7.1/linux64/include/python2.7 

然后跑到这来产生这样的文件a.so: -

gcc -shared a.o -o a.so 

当我从tclsh加载它时,它失败了。

$tclsh 
% load ./a.so 
couldn't load file "./a.so": ./a.so: undefined symbol: PyExc_RuntimeError 

我在这里采取正确的道路?如果没有,请向我解释出了什么问题,我该怎么做?

在此先感谢。

回答

2

目标代码需要链接到它在建立可加载库时所依赖的库。这意味着添加适当的-l...选项以及可能还有一些-L...选项。我猜这个选项将类似于-lpython27或类似的东西(链接到libpython27.so某处在您的库搜索路径;库搜索路径被修改为-L...选项),但我不知道。路径将取决于你的系统的设置和实验可能需要在你的一半。

它仍然可能不会作为Tcl中的可加载库。 Tcl期望有一个库初始化函数(在你的情况下,它会查找A_Init),它将Tcl_Interp*作为其唯一参数,以便库可以将它定义的命令安装到Tcl解释器上下文中。如果Python默认做了这样的事情,我会感到惊讶。这对你来说并没有失败,因为在内部dlopen()呼叫中仍然发生故障,而不是呼叫dlsym(),但我可以有把握地预测你仍然会面对他们。

“整合”这类功能的最简单方法是在子进程中运行该命令。

这里是Python代码,你可以使用:

import os 
import sys 

print sys.path 

,这里是Tcl的代码使用它:

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]] 

这不是最有效的方式,但它是超级容易使其因为你不必解决两种语言的编译和链接。这是程序员效率 ...

+0

嗨@donal thx的帮助。但我实际需要做的不仅仅是这些。我有一个包含对象类的包。我需要将所有这些转换为tcl可用包。对于我应该寻找什么或哪里的任何提示? – lionel319

1

也许看看tclpythonlibtclpy

两者都允许从Tcl调用Python代码。

但是,如果你想以更好的方式包装的东西,例如有更好的已经包装的API,也许你也应该看看Elmer,这似乎瞄准你的尝试任务。