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