关于如何使用Cython本地C库中的代码,我有一个关于最佳实践的问题。为了避免设置LD_LIBRARY_PATH
(或在/ usr / lib或类似目录中安装C库),我认为静态链接对我的用例来说是一个合适的解决方案。
但是,连接已静态链接的c函数并非易事。我可以cimport
另一个静态链接C代码的cython模块的唯一方法是用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)
def useit(): print(clib_return_3(4))
调用c_from_with_direct_compilation.useit()有效(下面的test.sh输出)。
但是当我尝试从另一个cython文件中使用clib_return_3
时,它失败了!用法是
cimport c_from def useit(): print(c_from.clib_return_3(4))
bash test.sh
测试所有使用情况,正如您所看到的,clib_return_3符号链接到的cython确实可以使用该符号,而另一个cython因此尝试导入该符号失败。 / p>
======================== 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
答案 0 :(得分:1)
您可以执行以下任一操作:
cdef extern from "path/header.h":
然后列出你将在cython中使用的函数defs。 (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
中,您使用2种不同的方式来包含C代码(使用动态库和使用目标文件)。除非您的C make规则非常复杂,否则第三个选项是将.c
文件列在与.pyx
文件相同的数组中,让distutils为您构建它们。
答案 1 :(得分:0)
在长时间盯着这个问题后,我想我知道发生了什么:
Cython-cdef函数名称被破坏,而extern函数没有名称错误并保留其原始名称。名称修改对于跨不同模块的功能的可发现性是必要的。因此,不能通过cimport
共享非损坏的名称 - 对于那些,正常的C共享库机制适用。