使用Ctypes将C ++代码嵌入到Python中(SpecialKEval)

时间:2014-03-31 20:20:20

标签: python c++ c ctypes

我正在编写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)

我做错了什么?

1 个答案:

答案 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)