python 3.x - Undefined symbol when importing cythonized c++ code -


i tried call c++ code python, using cython in minimal(ish) example:

# setup.py import numpy np import glob distutils.core import setup cython.distutils import build_ext distutils.core import setup cython.build import cythonize  setup(   name = "pytest",   version = "0.0.1",   author = "herbert",   #cmdclass = {'build_ext': build_ext},   py_modules = ['pytest'],   ext_modules = cythonize(     '_pytest.pyx',     language="c++",     sources=['testcpp.cpp'],     #extra_compile_args=['-fopenmp', '-o3', '-ffast-math'],     include_dirs = [np.get_include(), '.'],     #extra_link_args=['-fopenmp']   ) ) 
# pytest.py __future__ import division import os import time import numpy np import scipy.sparse _pytest import pyprint  pyprint() 
# _pytest.pyx # distutils: language = c++ # distutils: sources = testcpp.cpp  cimport cython  cdef extern void testprint ()  @cython.boundscheck(false) def pyprint():     testprint() 
#include <iostream>  void testprint() {   std::cout << "c++ @ work.\n"; } 

then 'compile' these:

#removing possible left overs: $ rm -rf build/ __pycache__/ _pytest.cpp $ rm -rf ~/venv3/lib/python3.4/site-packages/{_pytest.cpython-34m.so,pytest*}  $ python3 setup.py clean .../lib/python3.4/site-packages/cython/compiler/main.py:514: userwarning: got unknown compilation options, please remove: sources, include_dirs   warnings.warn(message) compiling _pytest.pyx because changed. cythonizing _pytest.pyx running clean  $ python3 setup.py install .../lib/python3.4/site-packages/cython/compiler/main.py:514: userwarning: got unknown compilation options, please remove: sources, include_dirs   warnings.warn(message) running install running build running build_py creating build creating build/lib.linux-x86_64-3.4 copying pytest.py -> build/lib.linux-x86_64-3.4 running build_ext building '_pytest' extension creating build/temp.linux-x86_64-3.4 x86_64-linux-gnu-gcc -pthread -dndebug -g -fwrapv -o2 -wall -wstrict-prototypes -g -fstack-protector --param=ssp-buffer-size=4 -wformat -werror=format-security -d_fortify_source=2 -fpic -i.../include -i/usr/include/python3.4m -c _pytest.cpp -o build/temp.linux-x86_64-3.4/_pytest.o cc1plus: warning: command line option ‘-wstrict-prototypes’ valid c/objc not c++ [enabled default] x86_64-linux-gnu-gcc -pthread -dndebug -g -fwrapv -o2 -wall -wstrict-prototypes -g -fstack-protector --param=ssp-buffer-size=4 -wformat -werror=format-security -d_fortify_source=2 -fpic -i.../include -i/usr/include/python3.4m -c testcpp.cpp -o build/temp.linux-x86_64-3.4/testcpp.o cc1plus: warning: command line option ‘-wstrict-prototypes’ valid c/objc not c++ [enabled default]  ### !!!! next statement shows `testcpp.cpp` file should compiled , linked `_pytest.cpython-34m.so`:  x86_64-linux-gnu-g++ -pthread -shared -wl,-o1 -wl,-bsymbolic-functions -wl,-bsymbolic-functions -wl,-z,relro -wl,-bsymbolic-functions -wl,-z,relro -g -fstack-protector --param=ssp-buffer-size=4 -wformat -werror=format-security -d_fortify_source=2 build/temp.linux-x86_64-3.4/_pytest.o build/temp.linux-x86_64-3.4/testcpp.o -o build/lib.linux-x86_64-3.4/_pytest.cpython-34m.so running install_lib copying build/lib.linux-x86_64-3.4/pytest.py -> .../lib/python3.4/site-packages copying build/lib.linux-x86_64-3.4/_pytest.cpython-34m.so -> ..../lib/python3.4/site-packages running install_egg_info writing ..../lib/python3.4/site-packages/pytest-0.0.1.egg-info 

however, when run (from homedirectory, , not project directory, make sure installed version used), dynamic linker can't find testprint symbol:

$ python3 -c 'import pytest;' traceback (most recent call last):   file "<string>", line 1, in <module>   file ".../lib/python3.4/site-packages/pytest.py", line 6, in <module>     _pytest import pyprint importerror: .../lib/python3.4/site-packages/_pytest.cpython-34m.so: undefined symbol: testprint 

the ... marks location of python 3 virtual environment. notice if inspect .so, testprint symbol found:

$ nm .../lib/python3.4/site-packages/_pytest.cpython-34m.so  | grep testprint                  u testprint 0000000000001e60 t _z9testprintv 

why testprint symbol not found python 3?

all frustration aside, found solution. _pytext.pyx gets processed _pytest.cpp, after preprocessing (-e switch in g++), declares:

extern "c" void testprint(void); 

this result of cython statement:

cdef extern void testprint () 

basically declared c function (with symbol testprint), whereas c++ function (with symbol _z9testprintv) defined in .so file. since testprint != _z9testprintv got undefined symbol: testprint

so how fix this? clueless best solution is, seems work:

cdef extern "testcpp.h":   cdef void testprint () 

Comments

Popular posts from this blog

Android : Making Listview full screen -

javascript - Parse JSON from the body of the POST -

javascript - Chrome Extension: Interacting with iframe embedded within popup -