C++ 方法需要引用,无法让 Cython 提供引用

标签 c++ pointers reference cython

我通过 Cython 将 Python 连接到一个名为 BulletPhysics 的 C++ 库。我已经完成了很多工作,但有一个问题让我烦恼。以下是在多个上下文中发生的问题的示例。

BulletPhysics.h 文件声明了一个方法,我将其复制并合并到我的 cdef 中,如下所示:

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 对象和 btRigidBody 对象存在“无效构造函数”库不提供不带参数的构造函数,出于可维护性的原因,我不想对库进行修改。

那么,如何在 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 语法,因此不可能使用 * 进行指针取消引用。而是使用 []。以下内容完成了所需的操作:

电机 = new btSliderConstraint(bs.bodies[nbi][0], bs.bodies[ji1][0], tra, trb, 1);

关于C++ 方法需要引用,无法让 Cython 提供引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43219293/

相关文章:

c# - 如何将带有 ref 参数的函数/方法添加到字典对象?

c++ - 为什么 const 引用可以指向常量而普通引用不能

c++ - 如何通过导入的目标可传递地设置 “CMAKE_EXE_LINKER_FLAGS”?

c++ - 如何使用 Cygwin 打开 RTTI?

c++ - 重复宏 n 次

c++ - 递归方法 C++

c++ - 声明指针/引用变量的首选方式?

c++ - 使用 boost 的 Glob 风格正则表达式模式匹配

c - 为什么 char *str;被宣布为越界

c - 指针新手试图找出为什么我的链接列表实现不起作用