gpt4 book ai didi

c++ - 从 Python 扩展调用 C++ 虚拟成员时崩溃

转载 作者:太空宇宙 更新时间:2023-11-04 14:15:17 30 4
gpt4 key购买 nike

我正在尝试围绕一些 C++ 类编写一个薄包装器,以便从 Python 调用它们。具体问题是,如果 virtual 在下面未被注释,则尝试创建 Foo() 会使解释器崩溃。我对将这段代码重写为 Boost::python、SWIG 或 Pyxxx 来解决这个问题不感兴趣——这是从一个更大的系统中摘录的,我想知道为什么会这样,尽管如果这些库中的任何一个解决了这个问题我很想知道他们是如何实现的。如果我设置一个扩展模块并在系统中注册类型,那么来自 Python 解释器的调用可以毫无问题地工作,无论是使用 extern "C" 还是只在类中使用静态成员在插槽中注册对于 Python 类型。

如果我将一个成员声明为虚拟成员,那么尝试调用它(在 Python 解释器的调用中)会导致崩溃,内存访问错误。访问的地址是我将类成员作为指针打印出来时得到的偏移量。我有具体的代码要遵循,但基本问题是:Python 调用的 C 运行时环境中是否有某些东西搞砸了虚拟类成员函数的发送? Python 是 v2.6.7,C++ 扩展正在由 GCC 4.2.1 编译。有相关问题提示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,您的评论让我走上了正轨。问题是 Foo 对象的内存正在被 Python 解释器 malloc。这并没有在我的其他代码中引起问题,因为它不依赖于初始化的 vtable。最简单的解决方案是使用 placement-new 来确保 ctor 实际被调用,然后虚拟成员正确工作:

 int initHook(PyObject *self, PyObject *args, PyObject *kwds)
{
new(self) Foo();
((Foo*)self)->insert();
}

On VTable pointers and malloc 有更详细的问答.

关于c++ - 从 Python 扩展调用 C++ 虚拟成员时崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11776711/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com