我遇到了C ++和Python相当错综复杂的交互问题,我希望社区可以帮助我。如果我的解释没有意义,请在评论中告诉我,我会尽力澄清。
我们的C ++代码库包含一个名为“IODevice”的父类,它是其他类的父类,如“File”和“Socket”等等。我们已经这样做了,因此在我们的大部分代码中,我们可以使用“IODevice”对象,这些对象实际上可能是文件或套接字或我们最初构造的任何内容。这一切都在C ++代码中正常工作。
我们已经开始为我们的一些对象构建Python绑定。我们不想修改原来的“文件”或“套接字”类;我们创建了“File”和“Socket”类的“FilePy”和“SocketPy”子类。这些* Py类包含必要的Python绑定代码。
这是问题的起点。假设我有一个“InputProcessorPy”C ++类,它具有适当的Python绑定。我希望能够在我的Python代码中构造它并传递一个“FilePy”或“SocketPy”对象,“InputProcessorPy”将从中提取数据。 “InputProcessorPy”中的Python绑定代码如下所示:
PyObject* InputProcessor::PyMake(PyObject* ignored, PyObject *args)
{
PyObject* cD_py;
IODevice* inputFile;
if (!PyArg_ParseTuple(args, "O", &cD_py))
return NULL;
inputFile = (IODevice*) cD_py;
inputFile->isReadable();
printf("------>>>> Done\n");
return (PyObject *) new CL_InputRenderer(*inputFile, InputProcessor::Type);
}
如果我运行此代码,当我调用inputFile的isReadable()方法时会出现分段错误,该方法实际上是IODevice基类的方法。
如果我这样做:
...
FilePy* inputFile;
...
inputFile = (FilePy*) cD_py;
inputFile->isReadable();
...
在这种情况下,代码可以正常工作。然而,这是不可取的,因为它假设我们传入一个“FilePy”对象,但事实并非如此;它可能是“SocketPy”或“BufferPy”或“StringPy”或任何其他类型的“IODevice”子类。
似乎Python绑定过程在某种程度上与我们尝试使用的C ++类继承结构不兼容。有没有人试图解决这样的问题?我们的C ++继承是错误的,还是我们应该在Python绑定中做一些不同的事情来使它工作?
答案 0 :(得分:4)
您的类型FilePy和IODevice是否派生自PyObject?否则,C ++编译器将解释:
inputFile = (IODevice*) cD_py;
为:
inputFile = reinterpret_cast<IODevice*> (cD_py);
而不是您的期望:
inputFile = dynamic_cast<IODevice*> (cD_py);
如果传递的实际类型不是PyObject,或者IODevice通过继承与PyObject无关,那么C ++编译器或运行时就无法知道如何找到合适的vtable。