[英]ctypes/C++ segfault accessing member variables
我對 python ctypes 模塊並不陌生,但這是我第一次嘗試在一個代碼中結合 C++、C 和 Python。 我的問題似乎與將ctypes 與 Python 和 C++ 一起使用時的 Seg fault非常相似,但是我似乎無法以相同的方式解決問題。
我有一個名為Header.cpp
的簡單 C++ 文件:
#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(); }
}
我使用以下方法將其編譯為共享庫:
g++ -c Header.cpp -fPIC -o Header.o
g++ -shared -fPIC -o libHeader.so Header.o
和一個名為test.py
的簡單 Python 包裝器:
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
成員,則程序不會出現段錯誤。
我對 C++ 的了解有限,但事實上我可以在 C 和 C++ 中按預期實現此功能,但在 Python 中卻不行,這讓我有點困惑。 任何幫助將不勝感激。
更新:感謝以下評論之一,問題已解決。 在這種情況下,需要為 C 函數顯式聲明 restype 和 argtypes。 即以下內容已添加到 python 代碼中:
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 綁定。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.