我正在编写Python应用程序,我需要能够从项目SpecialKEval中的文件getRankOfSeven
调用C ++函数SevenEval.cpp
。我必须运行C ++版本的SpecialKEval而不是python版本,原因很明显,因为我的应用程序的一个点是蒙特卡罗模拟计算获胜概率。
我已经编译了这些文件:
g++ -o SevenEval.so -shared -fPIC FiveEval.cpp SevenEval.cpp
将输出导入Python:
from ctypes import cdll
se = cdll.LoadLibrary('./SevenEval.so')
此加载没有问题,但se.SevenEval()
抛出AttributeError: ./SevenEval.so: undefined symbol: SevenEval
我已经读过,为了让ctypes工作,我需要有C对象/函数而不是C ++,并且用extrect "C" {
包裹它们,但我不是知道任何C / C ++(我只用Python编写代码)所以我不知道怎么做,而且这些例子太简单了,无法适应我的问题。
我在询问之前已经搜索了很多,也许解决方案就在那里,但由于我的C / C ++水平低,我不知道该怎么做。如果有人可以给我一些指导,详细的例子,或者为我这样做,我会非常高兴。
注意:在Ubuntu 13.10 64bit,Python2.7上运行
在Smoothware评论后编辑。
好的,这是SevenEval.h上函数的声明:
short getRankOfSeven(const int CARD1, const int CARD2, const int CARD3, const int CARD4, const int CARD5, const int CARD6, const int CARD7);
这就是我在文件末尾添加的内容:
extern "C" {
SevenEval* SevenEval_new(){ return new SevenEval(); }
short SevenEval_getRankOfSeven(SevenEval* foo, const int CARD1, const int CARD2, const int CARD3, const int CARD4, const int CARD5, const int CARD6, const int CARD7){ foo->getRankOfSeven(CARD1, CARD2, CARD3, CARD4, CARD5, CARD6, CARD7);}
}
这是我的Python文件:
from ctypes import cdll
lib = cdll.LoadLibrary('./SevenEval.so')
class SevenEval(object):
def __init__(self):
self.obj = lib.SevenEval_new()
def getRankOfSeven(self, c1, c2, c3, c4, c5, c6, c7):
lib.SevenEval_getRankOfSeven(self.obj, c1, c2, c3, c4, c5, c6, c7)
se = SevenEval() # Runs OK
print se.getRankOfSeven(1,2,3,4,5,6,7) # Gives Segmentation fault (core dumped)
我做错了什么?
答案 0 :(得分:1)
上一次编辑中的解决方案适用于32位Python。对于64位:
from ctypes import cdll
from ctypes import c_void_p
lib = cdll.LoadLibrary('./SevenEval.so')
lib.SevenEval_new.restype = c_void_p
class SevenEval(object):
def __init__(self):
self.obj = c_void_p(lib.SevenEval_new())
def getRankOfSeven(self, c1, c2, c3, c4, c5, c6, c7):
return lib.SevenEval_getRankOfSeven(\
self.obj, c1, c2, c3, c4, c5, c6, c7)