使用Cython来显示静态链接的c库符号

时间:2015-02-12 12:41:13

标签: python cython

关于如何使用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.pyxhttps://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项目中,我已经汇总了几种链接方式。我现在将重点关注文档中看似自然的方式。

https://github.com/HolgerPeters/cython-example/blob/master/cython-project/c_from_with_direct_compilation.pxd

cdef extern from "foo.h":
    extern int clib_return_3(int)

和相应的用例 https://github.com/HolgerPeters/cython-example/blob/master/cython-project/c_from_with_direct_compilation.pyx

def useit():
    print(clib_return_3(4))

调用c_from_with_direct_compilation.useit()有效(下面的test.sh输出)。

但是当我尝试从另一个cython文件中使用clib_return_3时,它失败了!用法是

https://github.com/HolgerPeters/cython-example/blob/master/cython-project/c_from_with_direct_compilation_user.pyx

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

2 个答案:

答案 0 :(得分:1)

您可以执行以下任一操作:

  1. cdef extern from "path/header.h":然后列出你将在cython中使用的函数defs。 (http://docs.cython.org/src/userguide/external_C_code.html#referencing-c-header-files
  2. 将C函数声明为extern。 (http://docs.cython.org/src/userguide/external_C_code.html#external-declarations
  3. (两种方法都适用于pyxpxd文件。

    附注:在setup.py中,您使用2种不同的方式来包含C代码(使用动态库和使用目标文件)。除非您的C make规则非常复杂,否则第三个选项是将.c文件列在与.pyx文件相同的数组中,让distutils为您构建它们。

答案 1 :(得分:0)

在长时间盯着这个问题后,我想我知道发生了什么:

Cython-cdef函数名称被破坏,而extern函数没有名称错误并保留其原始名称。名称修改对于跨不同模块的功能的可发现性是必要的。因此,不能通过cimport共享非损坏的名称 - 对于那些,正常的C共享库机制适用。