我有兴趣在
python中使用c类.看着
Calling C/C++ from python?,我决定尝试ctypes.但是,当我尝试更改类成员的值时,我得到段错误.
这是一个重现我的问题的简单示例:
C/C++方面:
#include <iostream> class Foo{ private: int mValue; public: void bar(){ std::cout << "Hello" << std::endl; } void setValue(int inValue) { mValue = inValue; std::cout << "Value is now: " << mValue << std::endl; } void setValue2() { mValue = 2; std::cout << "Value is now: " << mValue << std::endl; } }; extern "C" { Foo* Foo_new(){ return new Foo(); } void Foo_bar(Foo* foo){ foo->bar(); } void Foo_setValue(Foo* foo,int v) { foo->setValue(v); } void Foo_setValue2(Foo* foo) { foo->setValue2(); } }
代码在OSX上编译,包括:
g++ -c -fPIC foo.cpp -o foo.o && g++ -shared -Wl -o libfoo.dylib foo.o
python方面:
from ctypes import * lib = cdll.LoadLibrary('./libfoo.dylib') class Foo(object): def __init__(self): self.obj = lib.Foo_new() def bar(self): lib.Foo_bar(self.obj) def set(self,v): lib.Foo_setValue(self.obj,v); def set2(self): lib.Foo_setValue2(self.obj);
我可以毫无问题地调用bar,但如果我调用set或set2,我会遇到段错误.
f = Foo() f.bar() # Ok f.set(3) # Segfault
显然,我错过了一些东西.
解决方法
使用以下解决了问题:
def __init__(self): lib.Foo_new.restype = c_void_p # Needed self.obj = lib.Foo_new() def set(self,v): lib.Foo_setValue(c_void_p(self.obj),v) # c_void_p needed
阅读,它似乎是一个64位指针问题.