2010-07-16 25 views
2

我遇到了C++和Python之间错综复杂的交互问题,希望社区能够帮助我。如果我的解释没有意义,请在评论中告诉我,我会尽力澄清。我们如何正确地实现子类C++对象的Python绑定?

我们的C++代码库包含一个名为“IODevice”的父类,它是其他类(例如“File”和“Socket”等)的父类。我们已经这样做了,因此在我们的大部分代码中,我们可以通常使用“IODevice”对象,这些对象可能实际上是文件或套接字或我们最初构建的任何对象。这一切都在C++代码中正常工作。

我们已经开始为我们的一些对象构建Python绑定。我们不想修改原来的“文件”或“套接字”类;我们创建了“File”和“Socket”类的“FilePy”和“SocketPy”子类。这些* Py类包含必要的Python绑定代码。

以下是问题出现的地方。假设我有一个“InputProcessorPy”C++类,它具有适当的Python绑定。我希望能够在我的Python代码中构造它,并将它传递给“InputProcessorPy”将从中提取数据的“FilePy”或“SocketPy”对象。从“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绑定中做一些不同的事情来完成这项工作?

回答

4

是您的类型从PyObject派生的FilePy和IODevice?否则,C++编译器会解释:

inputFile = (IODevice*) cD_py; 

为:

inputFile = reinterpret_cast<IODevice*> (cD_py); 

,而不是你所期望的:

inputFile = dynamic_cast<IODevice*> (cD_py); 

如果传递的实际类型不是的PyObject,或IODevice不通过继承与PyObject相关,C++编译器或运行时无法知道如何找到适当的vtable。

+0

事实证明,IODevice与PyObject无关。如果这混淆了我们的演员阵容,那么我们需要提出一个不同的继承方案。 – dbisdorf 2010-07-16 20:56:37

相关问题