C++ API 声明在 Cython 中失败
我有两个文件 module.pyx
和 foo.cpp
。我想在 foo.cpp
中调用一个在 Cython 模块 module.pyx
中声明的函数。这个函数会返回一个指向向量的指针:
module.pyx
:
#distuils: language = c++
from libcpp.vector cimport vector
from cython.operator cimport dereference as deref
cdef api vector[int] *func():
cdef vector[int] *v = new vector[int]()
deref(v).push_back(3)
return v
foo.cpp
:
#include "module_api.h"
#include <vector>
#include <iostream>
using namespace std;
int main() {
import_module();
vector<int> *v = func();
cout << "v[0] = " << v[0] << endl;
}
我用下面的命令编译了 module.pyx
:
cython module.pyx --cplus
然后用这个命令编译 foo.cpp
:
g++ foo.cpp -I/Users/richizy/anaconda/include/python2.7/
但是它没有正常工作。我收到一个很大的错误信息,内容是“命名空间 'std' 中的 vector 不是一个类型”,还有很多其他的错误。问题出在哪里呢?
我使用的是 Anaconda 的 Python 版本,刚刚进行了干净的默认安装。
版本信息:
g++ (MacPorts gcc47 4.7.3_3+universal) 4.7.3
Cython 版本 0.20.1
Python 2.7.6 :: Anaconda 1.9.1 (x86_64)
Mac OS X 10.8.4
1 个回答
要在C或C++应用程序中使用Python引擎,你需要确保在你的main()
函数开始时调用Py_Initialize()
,并在结束时调用Py_Finalize()
。另外,你可能没有注意到的是,import_module()
函数实际上会产生一个错误,但它是通过Python的错误机制来处理的。你可以通过在import_module()
下面添加以下代码来让这个错误变得明显:
if (PyErr_Occurred())
{
PyErr_Print();
return -1;
}
如果你这样做,你会看到以下错误信息出现:
ImportError: No module named module
要使用Cython模块,你必须确保调用该模块的初始化函数,在这个例子中是initmodule()
。不幸的是,这个函数的声明似乎没有出现在生成的头文件中,所以我们需要手动将它添加到main函数的上方:
PyMODINIT_FUNC initmodule(void);
再加上把vector
的包含行放在最前面,以及在cout
行做一个小修正,代码就变成了:
#include <vector>
#include <iostream>
#include "module_api.h"
using namespace std;
PyMODINIT_FUNC initmodule(void);
int main() {
Py_Initialize();
initmodule();
import_module();
if (PyErr_Occurred())
{
PyErr_Print();
return -1;
}
vector<int> *v = func();
cout << "v[0] = " << (*v)[0] << endl;
Py_Finalize();
return 0;
}
在我的系统上,这样做的输出是:
v[0] = 3