2016-08-22 62 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,這似乎瞄準你的嘗試任務。