我正在尝试为C库编写一个Cython包装器。我仔细阅读了文档但我必须遗漏一些东西,因为我无法使用以下简单的Cython代码。
我从以下位置创建了一个共享库:
mathlib.c
#include "mathlib.h"
int add_one(int x){
return x + 1;
}
mathlib.h
extern int add_one(int x);
然后我像这样创建了库:
gcc -c mathlib.c gcc -shared -o libmathlib.so mathlib.o -lm
我的Cython文件是mathlib.pyx,cmathlib.pyd和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"]`enter code here`)
)
模块cymathlib.so已创建,但当我尝试在Python中导入时,我收到以下错误:ImportError:dlopen(./ cymathlib.so,2):找不到符号:_add_one引用自:./ cymathlib。所以预期在:./cymathlib.so"
中的平面命名空间答案 0 :(得分:2)
您的Extension
规范看起来有些问题,应该是这样的:
ext_modules = cythonize([Extension("cymathlib",
["cymathlib.pyx"],
libraries=["mathlib"],
library_dirs=["/place/path/to/libmathlib.so/here"]
)])
为了能够使用该模块,它必须能够在运行时找到libmathlib.so
,因为它将在该文件中查找add_one
的实际实现。除了将文件复制到/ usr / lib或/ usr / local / lib(并再次运行ldconfig)之外,您还可以设置环境变量以确保可以找到库:
export LD_LIBRARY_PATH=/place/full/path/to/libmathlib.so/here
也可以将C代码添加到您正在创建的python模块中(因此不再需要编译或使用libmathlib.so)。您只需将mathlib.c
文件添加到cython源列表中:
ext_modules = cythonize([Extension("cymathlib",
["cymathlib.pyx","mathlib.c"]
)])