[英]Crash calling C++ virtual member from Python extension
我正在嘗試為一些C ++類編寫一個瘦包裝,以從Python調用它們。 特定的問題是,如果在下面未注釋virtual
,則嘗試創建Foo()
會使解釋器崩潰。 我對將代碼重寫為Boost :: python,SWIG或Pyxxx來解決此問題不感興趣-這是從更大的系統中提取的內容,我想知道為什么會發生,盡管這些庫中的任何一個都可以解決此問題我很想知道他們是如何實施的。 如果我設置了擴展模塊並在系統中注冊類型,那么使用extern "C"
或僅在類中使用靜態成員在Python類型的插槽中注冊,Python解釋器的調用就可以正常工作。
如果我聲明一個成員為虛擬成員,則嘗試調用它(在Python解釋器的調用內)會導致崩潰,並導致錯誤的內存訪問。 訪問的地址是將類成員作為指針打印出來后得到的偏移量。 我要遵循特定的代碼,但是基本問題是:Python調用的C運行時環境中的某些內容是否破壞了虛擬類成員函數的發送? Python是v2.6.7,G ++ 4.2.1正在編譯C ++擴展。 有一些相關的問題建議Boost :: python支持這一點,他們是直接做到這一點還是通過類成員函數對其進行仿真?
// PythonType is a class that inherits from PyTypeObject and fills in defaults ...
extern "C" int initHook(PyObject *self, PyObject *args, PyObject *kwds);
class Foo
{
public:
static PythonType thePyType;
static void registerType(PyObject *module)
{
thePyType.tp_init = initHook;
PyType_Ready(&thePyType);
PyModule_AddObject(module, thePyType.tp_name, (PyObject*)&thePyType);
}
/*virtual*/ void insert()
{
printf("Inserted\n");
}
};
PythonType Foo::thePyType("Foo",sizeof(Foo));
extern "C" {
int initHook(PyObject *self, PyObject *args, PyObject *kwds)
{
((Foo*)self)->insert();
}
}
謝謝Let_Me_Be,您的留言使我誤入歧途。 問題是Python解釋器正在分配Foo對象的內存。 這不會在我的其他代碼中引起問題,因為它不依賴於初始化的vtable。 最簡單的解決方案是使用newplacement以確保ctor實際被調用,然后虛擬成員正常工作:
int initHook(PyObject *self, PyObject *args, PyObject *kwds)
{
new(self) Foo();
((Foo*)self)->insert();
}
關於On VTable指針和malloc,有更詳細的問答。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.