考虑如何在 Cython 中访问以下 C++ 静态内联类成员变量:
namespace my::name::space
{
class MyClass
{
public:
static inline int LIFE { 42 };
};
}
一个合理的
.pyx
文件可能是:
cdef extern from "mycpp.h" namespace "my::name::space":
cdef cppclass MyClass:
int LIFE
cdef class MyMgr:
def my_failing_function(self) -> None:
cdef int life = MyClass.LIFE
但这会在生成的 C++ 编译期间引发以下诊断:
src/dotbug/dotbug-mre.cpp: In function ‘PyObject* __pyx_pf_6dotbug_5MyMgr_my_failing_function(__pyx_obj_6dotbug_MyMgr*)’:
src/dotbug/dotbug-mre.cpp:2666:39: error: expected primary-expression before ‘.’ token
2666 | __pyx_t_1 = my::name::space::MyClass.LIFE;
| ^
这不是有效的 C++ 语法;句点应该是范围运算符
::
。如果您在生成的代码中更改它并构建,它就会正常工作。
ChatGPT 建议(在它崩溃并声称 Cython 无法访问静态成员变量之前)我使用
static int LIFE
作为我的 cdef 定义,但这会产生不同的错误,这是在 cythonization 期间出现的错误:
cdef extern from "mycpp.h" namespace "my::name::space":
cdef cppclass MyClass:
static int LIFE
^
------------------------------------------------------------
src/dotbug/dotbug-mre.pyx:3:19: Syntax error in C variable declaration
我在语法方面有什么遗漏吗?我注意到,如果我将其转换为非静态变量并实例化它,我就可以很好地访问它。
有关完整的可构建文件集,请参阅 Github Gist
咨询专家和 ChatGPT,似乎没有办法在 Cython 中正确声明这一点,但是有一个有效的解决方法可以生成有效的代码,即使用类作为命名空间并在其中声明成员变量:
cdef extern from "mycpp.h" namespace "my::name::space::MyClass":
int LIFE
cdef class MyMgr:
def my_failing_function(self) -> None:
cdef int life = LIFE