实例化Cython中的类派生的C++结构

2024-10-02 02:43:28 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图用Python将Python与子弹物理C++库接口。我想用C速度,或者接近C的速度,用最少的变量打包和从Python解包。我能够使用这种方法创建一个到OpenGL的Cython接口(尽管与子弹物理相比,OpenGL有一个更简单的、非面向对象的C-API)。我的OpenGL接口工作得很好,但是在与子弹物理接口方面进展缓慢。在

我已经阅读了Cython C++教程和其他相关文章,但到目前为止还没有运气。在

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

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

class btBroadphaseInterface
{
    ...

以及

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

btBroadphaseInterface* broadphase = new btDbvtBroadphase();

这样,因为在Cython中,我不能在C++中对BTDBVTBultFrand结构做一个“新”,我如何实例化这个结构,从类派生,以便调用所有初始化器并在里面设置方法?在

我在Cython中看到了一些关于继承限制的引用。在

很明显,我可以malloc()结构的空间,但我认为这对我没什么帮助。我看不出任何类型的演员会有什么帮助。在

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

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

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

    cdef cppclass btDbvtBroadphase(btBroadphaseInterface):
        pass

当我试图编写一个构造函数,对从类派生的这个结构执行“new”操作时,如下所示:

cdef class PbtDbvtBroadphase:
    cdef btBroadphaseInterface *bp

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

编译器失败:

Error compiling Cython file: ------------------------------------------------------------ ...

cdef class PbtDbvtBroadphase: cdef btBroadphaseInterface *bp

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

^

fun4.pyx:173:46: new operator can only be applied to a C++ class

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

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

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


Tags: 文件方法selfnew物理结构cythonclass
1条回答
网友
1楼 · 发布于 2024-10-02 02:43:28

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

cdef cppclass btDvbtBroadphase(btBroadphaseInterface):
    #etc
<> C++中结构和类的区别仅仅是成员的默认可见性。从Cython的观点来看,它的行为是一样的,所以告诉Cython与C++代码不匹配并不重要。在

(这也可能值得省略,告诉辛顿关于遗产的事。如果你不在Cython中使用继承,那么它就不需要知道了。通常情况下,不复制完整的层次结构,而只复制您需要的部分,这通常比较容易)


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

在标题.hpp公司名称:

^{pr2}$

在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

在设置.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
      )))

相关问题 更多 >

    热门问题