Cython:链接到库和调用函数

时间:2014-12-28 21:25:12

标签: c shared-libraries cython

我正在尝试为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"

中的平面命名空间

1 个答案:

答案 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"]
                                   )])