Reputation: 43
I am trying to write a Cython wrapper for a C Library. I have read through the docs carefully but I must be missing something since I cannot get the following simple Cython code to work.
I created a shared library from the following:
mathlib.c
#include "mathlib.h"
int add_one(int x){
return x + 1;
}
mathlib.h
extern int add_one(int x);
Then I created the library like so:
gcc -c mathlib.c gcc -shared -o libmathlib.so mathlib.o -lm
My Cython files are mathlib.pyx, cmathlib.pyd, and setup.py
cymathlib.pyx
from mathlib cimport add_one
def add_one_c(int x):
print add_one(x)
return x
mathlib.pyd
cdef extern from "mathlib.h":
int add_one(int x)
setup.py
from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize
setup(
ext_modules = cythonize([Extension("cymathlib", ["cymathlib.pyx"])], libraries ["mathlib"])
)
The module cymathlib.so is created but when I attempt to import it in Python I get the following error: ImportError: dlopen(./cymathlib.so, 2): Symbol not found: _add_one Referenced from: ./cymathlib.so Expected in: flat namespace in ./cymathlib.so"
Upvotes: 4
Views: 7901
Reputation: 3806
It looks like something went wrong with your Extension
specification, which should be something like:
ext_modules = cythonize([Extension("cymathlib",
["cymathlib.pyx"],
libraries=["mathlib"],
library_dirs=["/place/path/to/libmathlib.so/here"]
)])
To be able to use the module, it must be able to find libmathlib.so
at run time, since it will look in that file for the actual implementation of add_one
. Apart from copying the file to /usr/lib or /usr/local/lib (and running ldconfig again), you can also set an environment variable to make sure the library can be found:
export LD_LIBRARY_PATH=/place/full/path/to/libmathlib.so/here
It's also possible to add the C code into the python module you're creating (so no libmathlib.so will need to be compiled or used anymore). You just need to add the mathlib.c
file to the list of cython sources:
ext_modules = cythonize([Extension("cymathlib",
["cymathlib.pyx","mathlib.c"]
)])
Upvotes: 4