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.cpp
Writing a
setup.py
file 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
.c
code using the command line Cython compiler$ cython foo.pyx
Manually 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?