我在foo.cpp
中定义了一个非常简单的c++类:
class Foo
{
int x;
public:
Foo()
{}
Foo(int _x)
: x ( _x )
{}
int getX() { return x; }
void print()
{ std::cout << "Foo { " << x << "}" << std::endl; }
};
在尝试用cython包装它时,我用以下声明创建了foo.pxd
:
cdef extern from "foo.cpp":
cdef cppclass Foo:
Foo() except +
Foo(int) except +
int x
int getX()
void print()
然而,在试图构建这个,并cimport
它到我的pyx
源文件,它给了我以下编译错误:
Error compiling Cython file:
------------------------------------------------------------
...
cdef cppclass Foo:
Foo() except +
Foo(int) except +
int x
int getX()
void print()
^
------------------------------------------------------------
foo.pxd:9:13: Empty declarator
Error compiling Cython file:
------------------------------------------------------------
...
cdef cppclass Foo:
Foo() except +
Foo(int) except +
int x
int getX()
void print()
^
------------------------------------------------------------
foo.pxd:9:13: Syntax error in C variable declaration
我试图遵循这个教程,但它似乎不适合我的情况下工作。即使修改它使Foo::print
方法接受一个整数参数y
,并将foo.pxd
更新为void print(int)
,我也会得到相同的错误。
我可能做错了什么,为什么我得到这个行为?
问题不在于 print
是一个内置的函数。这很好。你可以覆盖内置函数的名字,没有问题。
list = 1 # perfectly valid code; (but may confuse future users)
问题是print
是内置的关键字。这是因为Cython在读取.pyx时默认使用Python 2语法(目前)。要解决这个问题,使用language_level=3
编译器指令。
Cython还能够在Cython中使用与C/c++中使用的名称不同的名称来修复这种类型的名称冲突。你可以用这个代替
cdef extern from "foo.cpp":
cdef cppclass Foo:
...
void cpp_print "print"()
这意味着Cython中的cpp_print
被翻译成c++中的print
。
答案其实很简单,但很有用。成员本身的名称是问题所在,而不是我在foo.pxd
中声明它的方式。考虑到print
是一个内置的python函数,它似乎与之冲突;将名称更改为任何不是内置方法/函数/类型或关键字的内容应该可以解决此问题。请注意,Python、Cython和C/c++关键字/函数都可以以同样的方式与此冲突。
@DavidW的回答(我已经接受了)更简洁地澄清了问题。我的解决方案是有效的,但列出的解释不是。