从Cython直接调用C++结构体构造函数

5
我正在尝试包装一些使用带有构造函数的结构体的C++代码,但是不知道该怎么做。
C++结构体:
typedef struct point_3d_t
{
    double x;
    double y;
    double z;

    point_3d_t(double x, double y, double z)
        : x(x)
        , y(y)
        , z(z)
        {}

} point_3d;

Cython封装器:
cdef extern from "./cppdar.hpp":
    ctypedef struct point_3d:
        point_3d(double, double, double)
        double x;
        double y;
        double z;

现在,我期望能够通过类似于cdef point_3d p1(v, v, v)(在cython文件中)的方式构建结构体,但我似乎无法弄清楚如何让cython使用提供的构造函数。
我尝试过:
  • cdef point_3d p1(v, v, v)
  • cdef point_3d p1 = point_3d(v, v, v)
  • cdef point_3d p1(0, 0, 0)
  • cdef point_3d p1 = point_3d(0, 0, 0)
其中v是明确的cdef double v = 0,但都没有成功。
使用普通的cdef point_3d p1p1.x = nnnn等等,但那很麻烦,我认为我应该能够使用默认构造函数。
尝试研究这个问题会产生很多与类构造函数相关的杂乱信息,这并没有帮助。
1个回答

3

好的,所以答案是在cython中你无法使用构造函数参数来堆栈分配C++对象,基本上根本不行

来自:https://groups.google.com/forum/#!topic/cython-users/fuKd-nQLpBs

Yes, it's a limitation, but it's a more fundamental issue than the parser. The construction and destruction of stack-allocated objects in C++ is intricately tied to their scope, and scoping rules are different in Python and C. For example, consider

if some_condition(): 
    x = Foo(1) 
else: 
    x = Foo(2, 3) 
return x.method() 

This simply can't be expressed as such in C++. Conversely

if (some_other_condition()) { 
    Foo_with_RIAA foo(x) 
} 
... 

wouldn't translate "correctly" Python scoping rules.

Now there are some cases where it could make sense, but significant code generation changes would have to be made, as currently all variables are declared at the top of a function (to follow the C89 standard, which some compilers enforce) but in C++ mode we would have to defer the declaration of the variable to it's instantiation (including avoiding any automatically inserted C-level {} scopes used for simplicity in code generation).

As one can always allocate such complicated objects on the heap, this isn't a significant limitation.

这是非常恼人的,因为这意味着在许多情况下,您根本无法包装缺少默认构造函数的类。


可怕、不好的hacky解决方法是将构造函数包装在一个简单的C(++)函数中,然后通过cython公开


我不确定我理解你的解决方法有什么作用?我认为你仍然需要一个默认构造函数。 - DavidW
@DavidW - 是的,你仍然会得到一个构造函数、构造和移动过程,但这比默认实例化,然后逐个设置成员要好得多。 - Fake Name
我相信Cython可以执行构造函数后的复制赋值/移动赋值: cdef point_3d p 然后稍后 p=point_3d(...)。您可能需要告诉它关于默认构造函数以及您使用的构造函数。 - DavidW
@DavidW - 是的,但我正在尝试删除默认构造函数,因为我希望能够避免出现意外未初始化的实例。 - Fake Name

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接