ctypes/C ++ segfault访问成员变量 [英] ctypes/C++ segfault accessing member variables
问题描述
我对python ctypes模块并不陌生,但这是我第一次尝试在一个代码中组合C ++,C和Python.我的问题似乎与 Seg错误类似当在Python和C ++中使用ctypes时,但是,我似乎无法以相同的方式解决问题.
I am no stranger to the python ctypes module, but this is my first attempt at combining C++, C and Python all in one code. My problem seems to be very similar to Seg fault when using ctypes with Python and C++, however I could not seem to solve the problem in the same way.
我有一个名为 Header.cpp
的简单C ++文件:
I have a simple C++ file called Header.cpp
:
#include <iostream>
class Foo{
public:
int nbits;
Foo(int nb){nbits = nb;}
void bar(){ std::cout << nbits << std::endl; }
};
extern "C" {
Foo *Foo_new(int nbits){ return new Foo(nbits); }
void Foo_bar(Foo *foo){ foo->bar(); }
}
我使用以下命令将其编译为共享库:
which I compile to a shared library using:
g++ -c Header.cpp -fPIC -o Header.o
g++ -shared -fPIC -o libHeader.so Header.o
和一个名为 test.py
的简单Python包装器:
and a simple Python wrapper called test.py
:
import ctypes as C
lib = C.CDLL('./libHeader.so')
class Foo(object):
def __init__(self,nbits):
self.nbits = C.c_int(nbits)
self.obj = lib.Foo_new(self.nbits)
def bar(self):
lib.Foo_bar(self.obj)
def main():
f = Foo(32)
f.bar()
if __name__ == "__main__":
main()
我希望当我打电话给test.py时,我应该将数字32打印到屏幕上.但是,我得到的只是一个细分错误.如果我更改构造函数以在堆栈上返回类实例(即,无需进行 new
调用),然后传递该对象,则程序将按预期执行.另外,如果我更改 Foo
类中的 bar
方法,使其不使用 nbits
成员,则程序不会出现段错误.
I would expect that when I call test.py, I should get the number 32 printed to screen. However, all I get is a segmentation fault. If I change the constructor to return the class instance on the stack (i.e. without the new
call) and then pass around the object, the program performs as expected. Also, if I change the bar
method in the Foo
class such that it does not use the nbits
member, the program does not seg fault.
我对C ++的了解有限,但是我可以像预期的那样在C和C ++中实现此功能,而在Python中无法实现这一事实,这有点令人困惑.任何帮助将不胜感激.
I have an limited understanding of C++, but the fact that I can make this function as expected in C and in C++ but not in Python is a little confusing. Any help would be greatly appreciated.
更新:由于下面的评论之一,该问题已解决.在这种情况下,需要为C函数同时显式声明restype和argtypes.即以下代码已添加到python代码中:
Update: Thanks to one of the comments below, the problem has been solved. In this case, an explicit declaration of both restype and argtypes for the C functions was required. i.e the following was added to the python code:
lib.Foo_new.restype = C.c_void_p
lib.Foo_new.argtypes = [C.c_int32]
lib.Foo_bar.restype = None
lib.Foo_bar.argtypes = [C.c_void_p]
推荐答案
我会尝试以下操作:
extern "C"
{
Foo *Foo_new(int nbits)
{
Foo *foo = new Foo(nbits);
printf("Foo_new(%d) => foo=%p\n", nbits, foo);
return foo;
}
void Foo_bar(Foo *foo)
{
printf("Foo_bar => foo=%p\n", foo);
foo->bar();
}
}
查看 foo
的值是否匹配.
此外,您可能希望查看Boost.Python来简化C ++对象的Python绑定创建.
Also, you might want to look at Boost.Python to simplify creating Python bindings of C++ objects.
这篇关于ctypes/C ++ segfault访问成员变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!