Reputation: 2122
I have two files module.pyx
and foo.cpp
. I want to be able to call a function, declared in the cython module module.pyx
, within foo.cpp
. This function returns a pointer to a vector:
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;
}
I've compiled module.pyx
with
cython module.pyx --cplus
and foo.cpp
with
g++ foo.cpp -I/Users/richizy/anaconda/include/python2.7/
but it is not working. I get a huge error stating "vector in namespace 'std' does not name a type", among many other things. What is the problem?
I am using the Anaconda Python distribution, which I just did a recent clean & default install.
Versions:
g++ (MacPorts gcc47 4.7.3_3+universal) 4.7.3
Cython version 0.20.1
Python 2.7.6 :: Anaconda 1.9.1 (x86_64)
Mac OS X 10.8.4
Upvotes: 4
Views: 1001
Reputation: 3806
To be able to use the python engine from a C or C++ application,
you need to make sure that Py_Initialize()
is called at the beginning
of your main()
function, and that Py_Finalize()
is called at the
end. What you also don't see is that the import_module()
function
actually produces an error, but it does this using the python error
mechanism. You can make this visible by adding the following code
below import_module()
:
if (PyErr_Occurred())
{
PyErr_Print();
return -1;
}
If you do that, you'll see the following error appear:
ImportError: No module named module
To be able to use a Cython module, you have to make sure
that that module's init function is called, in this case
initmodule()
. Unfortunatly it seems that the declaration of
this function is not present in the generated header file,
so we'll have to manually add it above the main:
PyMODINIT_FUNC initmodule(void);
Together with placing the vector
include line first and a small
fix in the cout
line, the code then becomes:
#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;
}
Which, at least on my system, produces the output:
v[0] = 3
Upvotes: 4