Fak*_*ame 5 python struct cython
我正在尝试包装一些使用带有构造函数的结构的 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;
Run Code Online (Sandbox Code Playgroud)
Cython 包装器:
cdef extern from "./cppdar.hpp":
ctypedef struct point_3d:
point_3d(double, double, double)
double x;
double y;
double z;
Run Code Online (Sandbox Code Playgroud)
现在,我希望能够通过类似的方式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,但没有工作。
使用 plain cdef point_3d p1、p1.x = nnnn等...,但这很烦人,而且我认为我不明白为什么我不应该使用默认构造函数。
尝试研究这个问题会产生很多与类构造函数相关的混乱,这没有帮助。
好吧,答案是你不能在 cython 中使用构造函数参数堆栈分配 C++ 对象,基本上根本无法:
来自: https: //groups.google.com/forum/#!topic /cython-users/fuKd-nQLpBs
是的,这是一个限制,但它是一个比解析器更基本的问题。C++ 中堆栈分配对象的构造和销毁与其作用域密切相关,并且 Python 和 C 中的作用域规则不同。例如,考虑
Run Code Online (Sandbox Code Playgroud)if some_condition(): x = Foo(1) else: x = Foo(2, 3) return x.method()这根本无法用 C++ 来表达。反过来
Run Code Online (Sandbox Code Playgroud)if (some_other_condition()) { Foo_with_RIAA foo(x) } ...不会“正确”翻译 Python 作用域规则。
现在在某些情况下它可能是有意义的,但必须进行重大的代码生成更改,因为目前所有变量都在函数顶部声明(遵循 C89 标准,一些编译器强制执行)但在 C++ 模式下我们必须将变量的声明推迟到其实例化(包括避免任何自动插入的 C 级 {} 作用域,以简化代码生成)。
由于人们总是可以在堆上分配如此复杂的对象,因此这并不是一个重大限制。
这是额外的加倍烦人,因为这意味着在许多情况下你根本无法包装缺少默认构造函数的类。
可怕的、不好的解决方法是将构造函数包装在一个简单的 C(++) 函数中,然后通过 cython 公开它。