使用Cython显示静态链接的clibrary符号

2024-10-02 18:17:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个关于如何在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.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显式使用externed声明吗?在

特定堆栈跟踪

由于这个问题一开始是一个相当开放的问题,我想更具体地鼓励大家回答。在

在命名的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

^{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

Tags: fromhttpsgithubmastercomreturn链接example
2条回答

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

  1. cdef extern from "path/header.h":,然后列出将在cython中使用的函数def。(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

(这两种方法都在pyxpxd文件中工作)。在

旁注:在您的setup.py中,您使用了两种不同的方法来包含C代码(使用动态库和使用对象文件)。除非您的C make规则非常复杂,否则第三种选择是将.c文件列在与.pyx文件相同的数组中,然后让distutils为您构建它们。在

在对这个问题进行了足够长时间的研究之后,我想我知道发生了什么:

Cython cdef函数是名称损坏的,而外部函数不是名称损坏的,而是保留其原始名称。为了在不同模块之间发现函数,需要对名称进行修改。因此,不能通过cimport共享未损坏的名称-对于这些名称,应用普通的C共享库机制。在

相关问题 更多 >