我有一个关于如何在Cython中使用本地C库中的代码的最佳实践的问题。为了避免设置LD_LIBRARY_PATH
(或者在/usr/lib或类似目录中安装C库),我认为静态链接是适合我的用例的解决方案。在
然而,连接静态链接的c函数是非常重要的。我能cimport
另一个cython模块中静态链接C代码的唯一方法是用cython函数指针解释所有导出的函数(请参见https://github.com/HolgerPeters/cython-example/blob/master/cython-project/c_with_ptrs.pyx和https://github.com/HolgerPeters/cython-example/blob/master/cython-project/c_with_ptrs.pxd)
仅仅将pxd中的原始C函数声明为extern似乎不起作用。我在Github上有一个示例项目,它隔离了不同的方法及其用法。在
https://github.com/HolgerPeters/cython-example
有什么想法吗?我可以告诉Cython显式使用extern
ed声明吗?在
由于这个问题一开始是一个相当开放的问题,我想更具体地鼓励大家回答。在
在命名的github项目中,我组装了几种链接方式。我现在将重点介绍文档中看起来很自然的方式。在
cdef extern from "foo.h": extern int clib_return_3(int)^{pr2}$
使用直接从_调用c__编译.useit()工程(测试.sh输出如下)。在
但是当我试图从另一个cython文件使用clib_return_3
时,它失败了!用法是
{a6}
cimport c_from def useit(): print(c_from.clib_return_3(4))
bash test.sh
测试所有的使用情况,如您所见,cython因此clib_return_3符号链接到的地方确实可以使用该符号,而另一个尝试导入该符号的cython则在这一点上失败了。在
======================== c_from_w/_direct_comp, interfacing fails (why?) Invoke from statically linked c_from_with_direct_compilation, invocation by c_from_with_direct_compilation_user Traceback (most recent call last): File "", line 1, in ImportError: ./c_from_with_direct_compilation_user.so: undefined symbol: clib_return_3 FAILURE ======================== c_from_w/_direct_comp Invoke from statically linked c_from_with_direct_compilation 3 SUCCESS
您可以执行以下任一操作:
cdef extern from "path/header.h":
,然后列出将在cython中使用的函数def。(http://docs.cython.org/src/userguide/external_C_code.html#referencing-c-header-files)extern
。(http://docs.cython.org/src/userguide/external_C_code.html#external-declarations)(这两种方法都在
pyx
和pxd
文件中工作)。在旁注:在您的
setup.py
中,您使用了两种不同的方法来包含C代码(使用动态库和使用对象文件)。除非您的C make规则非常复杂,否则第三种选择是将.c
文件列在与.pyx
文件相同的数组中,然后让distutils为您构建它们。在在对这个问题进行了足够长时间的研究之后,我想我知道发生了什么:
Cython cdef函数是名称损坏的,而外部函数不是名称损坏的,而是保留其原始名称。为了在不同模块之间发现函数,需要对名称进行修改。因此,不能通过
cimport
共享未损坏的名称-对于这些名称,应用普通的C共享库机制。在相关问题 更多 >
编程相关推荐