实例化C++;从cython中的类派生的结构 我试图用Python将Python与子弹物理C++库接口。我希望在C速度下,或者接近C速度的情况下,从Python进行最小的变量打包和解包。我能够使用这种方法创建一个到OpenGL的Cython接口(尽管与Bullet Physics相比,OpenGL有一个更简单、非面向对象的C API)。我的OpenGL接口工作得很好,但在与Bullet Physics接口方面进展缓慢 我已经阅读了Cython C++教程和其他相关文章,但到目前为止没有运气。

实例化C++;从cython中的类派生的结构 我试图用Python将Python与子弹物理C++库接口。我希望在C速度下,或者接近C速度的情况下,从Python进行最小的变量打包和解包。我能够使用这种方法创建一个到OpenGL的Cython接口(尽管与Bullet Physics相比,OpenGL有一个更简单、非面向对象的C API)。我的OpenGL接口工作得很好,但在与Bullet Physics接口方面进展缓慢 我已经阅读了Cython C++教程和其他相关文章,但到目前为止没有运气。,python,inheritance,cython,bullet,Python,Inheritance,Cython,Bullet,Bullet物理的组织有点复杂,但对于本例,希望知道btDbvtBroadphase是一个从btBroadphaseInterface类派生的结构就足够了。正如你可能知道的,结构可以从类派生(继承它们),并且两者之间没有太大的区别——至少在C++中。然而,Cython似乎只允许在类上执行“新建”,而不允许在结构上执行。我想这就是我的第一个问题 Bullet Physics.h文件中的声明如下所示: class btBroadphaseInterface { ... cdef class

Bullet物理的组织有点复杂,但对于本例,希望知道btDbvtBroadphase是一个从btBroadphaseInterface派生的结构就足够了。正如你可能知道的,结构可以从类派生(继承它们),并且两者之间没有太大的区别——至少在C++中。然而,Cython似乎只允许在类上执行“新建”,而不允许在结构上执行。我想这就是我的第一个问题

Bullet Physics.h文件中的声明如下所示:

class btBroadphaseInterface
{
    ...
cdef class PbtDbvtBroadphase:
    cdef btBroadphaseInterface *bp

    def __cinit__(self):
        self.bp=<btBroadphaseInterface *> new btDbvtBroadphase()

< >我在Cython中试图复制的C++代码非常简单的一行是:

btBroadphaseInterface* broadphase = new btDbvtBroadphase();

这样,因为在Cython中,我不能在C++中对BTDBVTBultFrand结构做一个“新”,我如何实例化这个结构,从类派生,以便调用所有初始化器,并在内部设置方法? 我在Cython中看到一些关于继承限制的引用

很明显,我可以为建筑留出空间,但我认为这对我帮助不大。我看不出任何类型的铸造会有什么帮助

我有Cython“.pxd”的东西显示了我如何从.h文件中执行cdef外部程序,但我认为这无助于澄清这个问题,所以我将省略它,除非有人认为它可能有用

我尝试了许多cdefs的变体,但都没有成功。下面是它现在的样子:

cdef extern from "bullet/btBulletDynamicsCommon.h":
    cdef cppclass btBroadphaseInterface:
        pass

    cdef cppclass btDbvtBroadphase(btBroadphaseInterface):
        pass
当我尝试编写一个构造函数,它将在这个从类派生的结构上执行“新建”操作时,如下所示:

class btBroadphaseInterface
{
    ...
cdef class PbtDbvtBroadphase:
    cdef btBroadphaseInterface *bp

    def __cinit__(self):
        self.bp=<btBroadphaseInterface *> new btDbvtBroadphase()
cdef类PbtDbvtBroadphase:
cdef BTBroadphase接口*bp
定义(自我):
self.bp=新的btDbvtBroadphase()
编译器出现以下故障:

编译Cython文件时出错: ------------------------------------------------------------

cdef类PBTDBVTBT道路阶段: cdef BTBroadphase接口*bp

def __cinit__(self):
    self.bp=<btBroadphaseInterface *> new btDbvtBroadphase()
def\uuuu cinit\uuuu(自):
self.bp=新的btDbvtBroadphase()
^

Fun4.Pyx:173:46:新的运算符只能应用于C++类

编辑:改进的标题,我最初只输入了一串关键字

Edit2:添加了cdefs和编译器输出


我接受了非常耐心的@DavidW的回答,因为它证明了事情应该是可行的。我想发生的事情是,我有一个与.pyx文件同名的.pxd文件,该文件被集成到构建中,尽管我没有使用distutils,而只是从命令行使用cython。当我认为我的构建方法可能不会给出与distutils/setup.py方法相同的结果时,.pxd是早期测试遗留下来的。我确信我的构建方法与问题无关,于是回到了我的首选方法(将cdefs放在.pyx文件中,只需通过一个简单的shell脚本进行编译和链接,如我下面的一条评论所示),但.pxd文件仍然存在,而且在我不知情的情况下仍然被cython编译器悄悄地拉了进来。我发现这一点是因为我注意到自己在编译时遇到了“重新声明”的错误。我错过了正在滚动的“重新声明”,只看到了新构造函数尝试中的错误。

最简单的选择就是告诉Cython它是一个类:

cdef cppclass btDvbtBroadphase(btBroadphaseInterface):
    #etc
<> C++中结构和类的区别仅仅是成员的默认可见性。从Cython的观点来看,它的行为是一样的,所以你告诉Cython的不匹配C++代码并不重要。 (也可以省略告诉Cython继承的内容。如果你不在Cython中使用继承,那么它就不需要知道。不复制完整的层次结构通常更容易,而只复制你需要的位)


编辑:以下代码适用于我:

header.hpp:

class btBroadphaseInterface {

};

struct btDbvtBroadphase : btBroadphaseInterface {

};
pymod.pyx:

cdef extern from "header.hpp":
    cppclass btBroadphaseInterface:
        pass

    cppclass btDbvtBroadphase(btBroadphaseInterface):
        pass

cdef class PyBroadphase:
    cdef btBroadphaseInterface* pt
    def __cinit__(self):
        self.pt = new btDbvtBroadphase()

    def __dealloc__(self):
        del self.pt
setup.py

from distutils.core import setup, Extension
from Cython.Build import cythonize

setup(ext_modules = cythonize(Extension(
           "pymod",                                # the extension name
           sources=["pymod.pyx",], # the Cython source and
                                                  # additional C++ source files
           language="c++",                        # generate and compile C++ code
      )))

关于你最后的评论,我不能真正改变继承的结构,因为这个库是由其他人生成的,我只是想钩住它。我可以对它进行修改,但这将成为一个令人头痛的问题。关于您的第一个建议,它与我所做的不同,它在括号中有btBroadphaseInterface,可能表示继承。我现在正在测试它,以及它的变体,但它似乎没有帮助。一旦我用尽了所有可能,我会再次回复。谢谢。最后一条评论是“如果你没有必要的话,就不要告诉Cython关于遗产的事”。它并不是建议更改C++代码对象,我想您的意思是:<代码> cdef cppclass btDbvtBroadphase(BtBuleStimeIdFieldId接口):用dvt,实际结构名。关于跳过继承,我不知道我怎么能做到这一点。我想实例化的是一个从类派生的结构。我不知道如何在Cython中实例化派生结构(包括方法等)。我有以下内容:
cdef extern来自“bullet/btBulletDynamicCommon.h”:cdef cppclass btDbvtBroadphase(btBroadphaseInterface):pass
(抱歉,注释中的换行似乎不正确)当我试图编译
cdef类PbtDbvtBroadphase:cdef btBroadphaseInterface*bp def\uu cinit\uuu(self):self.bp=new btDbvtBroadphase()
时,我得到一个错误“fun4.pyx:172:46:new operator can o