I have exactly copied the example code given in the Cython documentation for wrapping C++ classes. I can successfully build and import the rect.so extension using distutils and the cythonize() method, i.e. by:
Putting the following directives at the top of
rect.pyx:# distutils: language = c++ # distutils: sources = Rectangle.cppWriting a
setup.pyfile that contains this:from distutils.core import setup from Cython.Build import cythonize setup( name = "rectangleapp", ext_modules = cythonize('*.pyx'), )Calling
$ python setup.py build_ext --inplace
However, when I'm wrapping C code in Cython I often find it more convenient to compile individual extensions manually from the command line, i.e.:
Generate the
.ccode using the command line Cython compiler$ cython foo.pyxManually compile it using
gcc:$ gcc -shared -fPIC -O3 -I /usr/lib/python2.7 -L /usr/lib/python2.7 \ foo.c -lpython2.7 -o foo.so
I've tried applying the same process to build the rect.so example above:
$ cython --cplus rect.pyx
$ g++ -shared -fPIC -O3 -I /usr/lib/python2.7 -L /usr/lib/python2.7 \
rect.cpp -lpython2.7 -o rect.so
Both the Cython and g++ compilation steps seem to succeed - I don't get any command line output, and at the end I have a rect.so built. However, when I then try to import the module I get an undefined symbol error:
In [1]: import rect
---------------------------------------------------------------------------
ImportError Traceback (most recent call last)
<ipython-input-1-ba16f97c2145> in <module>()
----> 1 import rect
ImportError: ./rect.so: undefined symbol: _ZN6shapes9Rectangle9getLengthEv
What's the correct procedure for manually compiling Cython code that wraps C++ classes?