C++方法需要参考,无法让Cython提供
C++ method demands reference, can't get Cython to provide one
我正在通过Cython将Python连接到一个名为Bullet Physics的C++库。我有很多工作,但有一个问题困扰着我。下面是在多个上下文中出现的问题的示例。
一个子弹物理.h文件声明了一个方法,我复制它并合并到我的cdefs中,如下所示:
cdef cppclass btSliderConstraint:
btSliderConstraint *btSliderConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, bool useLinearReferenceFrameA)
问题是如何在对此方法的 Cython 调用中指定 rbA 和 rbB引用(&rbA 和 &rbB)。我有很多指向四处浮动的btRigidBody对象的指针,但是此方法的声明要求参数是引用的(除非我弄错了)。
如果我尝试只为 rbA 和 rbB 提供指向 btRigidBody 对象的指针,cython 编译器会抱怨,这是可以理解的:
Error compiling Cython file:
------------------------------------------------------------
cdef btRigidBody *b1
cdef btRigidBody *b2
# bs.bodies is an array of pointers to btRigidBody objects, nbi and ji1 are integer indices
b1 = bs.bodies[nbi]
b2 = bs.bodies[ji1]
motor = new btSliderConstraint(b1, b2, tra, trb, 1);
^
------------------------------------------------------------
fun4.pyx:922:41: Cannot assign type 'btRigidBody *' to 'btRigidBody'
我试图投射或取消引用之类的尝试都没有使这项工作。这似乎很容易在普通C++但在 Cython 中,我尝试过的任何内容似乎都不起作用。
如果我能够简单地声明一个 btRigidBody 类型的变量,如下所示:
cdef btRigidBody rbA
那么我相信我可以将其作为参数传递,编译器不会抱怨。我在其他情况下这样做并且有效。但是,我不想在这里这样做,因为我已经有一个指向我要作为参数传递的对象的指针,而且,以这种方式执行操作需要为 btRigidBody 对象存在"nullarity 构造函数",并且库不提供不带参数的构造函数,并且出于可维护性的原因,我不想对库进行修改。
那么,如何在 Cython 中将指针转换为我拥有的 btRigidBody 对象,转换为我需要的 btRigidBody 引用?
编辑:
明显使用 * 来取消引用指针在 Cython 中不起作用(尽管我认为它会在 C++ 中起作用)。在Cython中,它给出了一系列令人困惑的错误:
Error compiling Cython file:
------------------------------------------------------------
...
cdef btRigidBody *b1
cdef btRigidBody *b2
# bs.bodies is an array of pointers to btRigidBody objects, nbi and ji1 are integer indices
b1 = bs.bodies[nbi]
b2 = bs.bodies[ji1]
motor = new btSliderConstraint(*b1, *b2, tra, trb, 1);
^
------------------------------------------------------------
fun4.pyx:922:34: Non-trivial keyword arguments and starred arguments not allowed in cdef functions.
Error compiling Cython file:
------------------------------------------------------------
...
cdef btRigidBody *b1
cdef btRigidBody *b2
# bs.bodies is an array of pointers to btRigidBody objects, nbi and ji1 are integer indices
b1 = bs.bodies[nbi]
b2 = bs.bodies[ji1]
motor = new btSliderConstraint(*b1, *b2, tra, trb, 1);
^
------------------------------------------------------------
fun4.pyx:922:38: Cannot convert 'btRigidBody *' to Python object
Error compiling Cython file:
------------------------------------------------------------
...
cdef btRigidBody *b1
cdef btRigidBody *b2
# bs.bodies is an array of pointers to btRigidBody objects, nbi and ji1 are integer indices
b1 = bs.bodies[nbi]
b2 = bs.bodies[ji1]
motor = new btSliderConstraint(*b1, *b2, tra, trb, 1);
^
------------------------------------------------------------
fun4.pyx:922:43: Cannot convert 'btRigidBody *' to Python object
Error compiling Cython file:
------------------------------------------------------------
...
cdef btRigidBody *b1
cdef btRigidBody *b2
# bs.bodies is an array of pointers to btRigidBody objects, nbi and ji1 are integer indices
b1 = bs.bodies[nbi]
b2 = bs.bodies[ji1]
motor = new btSliderConstraint(*b1, *b2, tra, trb, 1);
^
------------------------------------------------------------
fun4.pyx:922:48: Cannot convert 'btTransform' to Python object
Error compiling Cython file:
------------------------------------------------------------
...
cdef btRigidBody *b1
cdef btRigidBody *b2
# bs.bodies is an array of pointers to btRigidBody objects, nbi and ji1 are integer indices
b1 = bs.bodies[nbi]
b2 = bs.bodies[ji1]
motor = new btSliderConstraint(*b1, *b2, tra, trb, 1);
^
------------------------------------------------------------
fun4.pyx:922:53: Cannot convert 'btTransform' to Python object
Error compiling Cython file:
------------------------------------------------------------
...
cdef btRigidBody *b1
cdef btRigidBody *b2
# bs.bodies is an array of pointers to btRigidBody objects, nbi and ji1 are integer indices
b1 = bs.bodies[nbi]
b2 = bs.bodies[ji1]
motor = new btSliderConstraint(*b1, *b2, tra, trb, 1);
^
------------------------------------------------------------
fun4.pyx:922:34: Cannot convert Python object to 'btSliderConstraint *'
Error compiling Cython file:
------------------------------------------------------------
...
cdef btRigidBody *b1
cdef btRigidBody *b2
# bs.bodies is an array of pointers to btRigidBody objects, nbi and ji1 are integer indices
b1 = bs.bodies[nbi]
b2 = bs.bodies[ji1]
motor = new btSliderConstraint(*b1, *b2, tra, trb, 1);
^
------------------------------------------------------------
fun4.pyx:922:34: Storing unsafe C derivative of temporary Python reference
由于 Cython 的目标是保留 Python 语法,因此无法使用 * 进行指针取消引用。而是使用 []。以下内容可以执行所需的操作:
motor = new btSliderConstraint(bs.bodies[nbi][0], bs.bodies[ji1][0], tra, trb, 1);
- 为什么在运行时没有向我们提供有关分段错误的更多信息?
- 架构决策:返回std::future还是提供回调
- 何时提供默认参数作为模板参数
- 无法在windows控制台中为C++程序提供必要的输入
- 我可以做些什么来消除或最小化这种将提供相同功能和行为的代码重复
- 提供与TMP和SFINAE的通用接口
- 是否值得降低我的代码的可读性,以便在出现内存不足错误时提供异常安全性?
- 为 std::variant 提供一个运算符 ==
- WinSock2:connect() 提供"连接被拒绝"
- COUT 无法提供输出可能是由于内联组装
- 我的 If Else 语句无法在向量 (C++) 中提供最大值
- 将 PCL 链接到 Cython C++ 模块
- 与其他编译器相比,相同的代码在工作室Microsoft提供不同的输出
- Linux承诺的内存比它所能提供的要多
- 将数组/向量发送到 c++ 脚本的 cython 示例
- std::p romise::set_value() 和 std::future::wait() 是否提供内存围栏?
- Cython:无法分配给 2D 矢量
- C++ 确保子类为常量提供自定义值
- C++有什么方法可以在既不调用函数模板也不提供其模板参数的情况下引用函数模板?
- C++方法需要参考,无法让Cython提供