简体   繁体   English

使用Cython公开静态链接的c库符号

[英]Use Cython for exposing statically linked c-library symbols

I have a question on best practice on how to use code from a local C library with Cython. 我对如何在Cython中使用本地C库中的代码的最佳实践有一个疑问。 In order to avoid setting the LD_LIBRARY_PATH (or installing the C library in /usr/lib or similar directories), I think static linking would be a suitable solution for my use case. 为了避免设置LD_LIBRARY_PATH (或在/ usr / lib或类似目录中安装C库),我认为静态链接将是适合我的用例的解决方案。

However, interfacing the c functions that have been statically linked is non-trivial. 但是,连接已经静态链接的c函数并非易事。 The only way I could cimport another cython module that has statically linked C code in it was to paraphrase all exported functions with Cython function pointers (see https://github.com/HolgerPeters/cython-example/blob/master/cython-project/c_with_ptrs.pyx and https://github.com/HolgerPeters/cython-example/blob/master/cython-project/c_with_ptrs.pxd ) 我可以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

Just declaring the original C function in the pxd as extern does not seem to work. 仅将pxd中的原始C函数声明为extern似乎不起作用。 I have exemplary project on Github which isolates different approaches and their usage. 我在Github上有一个示范项目,它隔离了不同的方法及其用法。

https://github.com/HolgerPeters/cython-example https://github.com/HolgerPeters/cython-example

Any ideas on this? 有什么想法吗? Can I tell Cython to explicitly use the extern ed declarations? 我可以告诉Cython显式使用extern ed声明吗?

Specific Stack-Trace 特定堆栈跟踪

As the question started as a rather open one, I would like to make it more specific to encourage answers. 由于这个问题是一个比较开放的问题,因此我想更具体地鼓励人们回答。

In the named github project I have assembled several ways of linking. 在命名的github项目中,我组装了几种链接方式。 I will focus now on the way that seems natural from the documentation. 我现在将集中于文档中看起来很自然的方式。

https://github.com/HolgerPeters/cython-example/blob/master/cython-project/c_from_with_direct_compilation.pxd 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)

and a use case in the corresponding https://github.com/HolgerPeters/cython-example/blob/master/cython-project/c_from_with_direct_compilation.pyx 以及相应https://github.com/HolgerPeters/cython-example/blob/master/cython-project/c_from_with_direct_compilation.pyx中的用例

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

Invocation of c_from_with_direct_compilation.useit() works (test.sh output below). 调用c_from_with_direct_compilation.useit()起作用(下面的test.sh输出)。

But then when I try to use clib_return_3 from another cython file, it fails! 但是,当我尝试从另一个cython文件中使用clib_return_3 ,它将失败! Usage is 用法是

https://github.com/HolgerPeters/cython-example/blob/master/cython-project/c_from_with_direct_compilation_user.pyx 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 tests all usage cases, and as you can see, the cython so where the clib_return_3 symbol is linked into can indeed use that symbol, whereas the other cython so trying to import that symbol fails at this. 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

You can do either of: 您可以执行以下任一操作:

  1. cdef extern from "path/header.h": and then list the function defs you'll use in cython. cdef extern from "path/header.h":然后列出要在cython中使用的函数defs。 ( http://docs.cython.org/src/userguide/external_C_code.html#referencing-c-header-files ) http://docs.cython.org/src/userguide/external_C_code.html#referencing-c-header-files
  2. declare the C functions as extern . 将C函数声明为extern ( http://docs.cython.org/src/userguide/external_C_code.html#external-declarations ) http://docs.cython.org/src/userguide/external_C_code.html#external-declarations

(Both methods work in pyx and pxd files). (这两种方法都可以在pyxpxd文件中使用)。

Side note: in your setup.py , you're using 2 different ways to include the C code (using the dynamic library & using the object file). 旁注:在setup.py ,您使用2种不同的方式包含C代码(使用动态库和使用目标文件)。 Unless your C make rules are really complicated, a third option is to just list the .c files in the same array as the .pyx files and let distutils build them for you. 除非您的C make规则真的很复杂,否则第三个选择是仅将.c文件与.pyx文件放在同一数组中,然后让distutils为您构建它们。

After staring long enough at this problem I think I know what is going on: 在凝视了这个问题足够长时间之后,我想我知道发生了什么事:

Cython-cdef-functions are name mangled, whereas extern functions are not name-mangled and keep their original names. Cython-cdef函数名称混乱,而extern函数没有名称混杂,并保留其原始名称。 Name mangling is necessary for discoverability of functions across different modules. 为了在不同模块之间发现功能,必须进行名称修饰。 So non-mangled names cannot be shared via cimport - for those, the normal C shared library mechanisms apply. 因此,无法通过cimport共享非混合名称-对于这些名称,将应用常规C共享库机制。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 将 C 库与 Cython 一起使用时出现错误 - I get an error, when using C-library with Cython 使用pyx / pxd文件中的函数工厂为C库生成cython函数包装器 - Using function factories in pyx/pxd files to generate cython function wrappers for C-library Cython 在 python 和具有未知大小字符数组的 c 库之间进行交互 - Cython to interface between python and c-library with unknown size char array 我如何在SWIG中包装一个C库,而SWIG通常在C编译期间被链接? - How can I wrap a C-Library in SWIG, which has usually to be linked during C-compilation? 从 Python (ctypes) 调试 C 库 - Debug C-library from Python (ctypes) 使用 Cython 将 Python 代码编译为静态链接的可执行文件 - Compile Python code to statically linked executable with Cython 使用cython将c ++函数暴露给python - Exposing a c++ function to python using cython 如何使用C库刷新Python程序中的内存? - How do i flush memory in a Python program with C-library? setuptools:从 C++ 代码构建共享库,然后构建链接到共享库的 Cython 包装器 - setuptools: build shared library from C++ code, then build Cython wrapper linked to shared library 从python调用静态链接的C库在Windows上永久挂起,但在OSX或linux上永远挂起 - Calling statically linked C library from python hangs forever on windows but not OSX or linux
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM