python - 可以围绕现有的大型C库自动生成Cython绑定(bind)吗?

标签 python c cython

换句话说:*.h/*.c --[??POSSIBLE??]--> *.pxd/*.pyx

好。我已经做完了(希望)在Internet上进行了足够的挖掘-但是我认为这是一个好问题,所以我将直接询问。

有一些相关的问题(例如Generate python bindings, what methods/programs to useWrapping a C library in Python: C, Cython or ctypes?),但是并不能完全概括我所问的情况,这也许是一种更“高级”的方法(特别是针对现有的库,而不是生成新的库) C(来自python)。

我有一个little bit的经验,这是我自己在使用Cython之前包装的一小段代码。 Cython对速度和可维护性大加赞赏。对于少量的代码,这在我的书中是可以的-但是,这次我的工作更多了……

three great virtues of a programmer的第一个之后,我想以最小的努力做到这一点。

因此,这里的真正问题是如何通过自动化方式简化.pxd文件(可能还有.pyx文件)的创建(即,以节省时间并避免错误键入内容)。

This here似乎是关于如何执行此操作的唯一真正的提示/注释-但是它上的大多数项目都是已失效,旧的或sourceforge。许多似乎只适用于C++(这就是我在这里使用的C)。

有人还在使用吗?最近?有人有这样做的工作流程或最佳做法吗?我只是手工做就更好了吗?

我的库由一组头文件很好地定义。一个包含所有C结构/类型的def,另一个包含所有函数的原型(prototype)。但这是loooonnnggg ...

感谢您的提示。

更新(2015年8月25日):

是的,所以在过去的几个月里,我有空的时候尝试了:

  • CFFI(感谢@David指出)-有一个崇高的目标:“在不学习第三语言的情况下从Python调用C代码:现有的替代方法要求用户学习 Realm 特定的语言(Cython,SWIG)或API(ctypes)” -但是它不符合要求,因为它在实际的python文件中包含了相当程度的嵌入式C代码(或将其加载到其中),这对于大型库来说是一个相当手动的过程,也许我错过了一些东西…
  • SWIG是Python绑定(bind)的祖父,并且非常扎实。但是从根本上讲,据我所知它并不是“放手”的-也就是说,您需要一个单独的规范文件。例如,您必须编辑所有C头文件以指示使用#define SWIG_FILE_WITH_INIT构建python模块或使用其他注释。 SIP在这里有同样的问题。您不会从 header 中自动生成,而是对其进行修改以包括您自己的指令和注释,并创建一个完整的规范文件。
  • cwrap-我在Mac上,因此我将此版本用于clang。 https://github.com/geggo/cwrap确实很糟糕的文档-但是使用源代码,我终于让它运行并生成了…。一个非常简单的结构 header 中的空.pyx文件。不太好。
  • xdress-这表明了希望。该网站已关闭,因此文档实际上似乎是here。有大量的工作要做,看起来很容易使用。但是它需要所有的llvm header (以及正确链接的clang版本)。我不得不使用brew install llvm —with-clang。有一个xdress clang-3.5分支,但似乎没有完成足够的修复。我尝试点击自制软件/版本以获取早期版本的clang(安装llvm33 / llvm34),并建立了它。无论如何,我离开了……对于一个简单的例子来说,它工作得很好,但是整个库所产生的ctypes文件很乱,因此拒绝构建。 AST C-> Python中的内容有些错误...
  • ctypesgen不是我在原始搜索中遇到的。该文档非常稀疏-或者您可以将其称为简洁。在过去的四年中,它似乎还没有做太多的工作(并且人们在问题 list 上询问开发人员是否打算继续该项目)。我曾尝试运行它,但遗憾的是,它似乎因我怀疑/似乎像Clang编译器cdefs.h使用_attribute_的问题而失败了。我尝试了-std=c11之类的方法,但无济于事。

  • 总之,在我看过的所有内容中,我认为xdress最接近于自动生成的python绑定(bind)。对于给出的简单示例来说,它工作得很好,但是无法处理更复杂的现有库 header ,包括所有前向声明,枚举类型,空指针的复杂性……似乎设计得很好并且(有一段时间)维护良好的项目,因此,如果有人再次尝试解决这些问题,可能会有某种方法来规避这些问题。

    仍然存在问题,是否有人拥有从C header 自动生成python包装器的强大工具链?我认为现实是,总有一些手动工作,因为CFFI看起来是最“现代”的方法(我遇到的最好的概述/比较之一是here)-但它始终涉及经过特殊编辑的cdef()版本任何头文件(例如Using Python's CFFI and excluding system headers)。

    最佳答案

    我发现ctypesgen非常适合自动生成。我只将其与一个或两个希望开源的python模块一起使用,到目前为止,我一直很高兴。这是一个将它与zlib一起使用的简单示例,但我也刚刚在其他一些库中成功尝试过:
    (编辑:我知道您提到过ctypesgen在Mac上存在问题,所以也许它需要有人对其进行调整才能在OSX上工作-我在家中没有OSX或尝试使用它。)

    获取ctypesgen:

    git clone https://github.com/davidjamesca/ctypesgen.git
    

    运行简短脚本以调用ctypesgen(将zlib信息替换为另一个库):
    import os                           
    
    ZLIB_INC_DIR = "/usr/include"       
    ZLIB_LIB_DIR = "/usr/lib/x86_64-linux-gnu"       
    ZLIB_LIB = "libz.so"       
    ZLIB_HEADERS = "/usr/include/zlib.h"       
    
    # Set location of ctypesgen.py                                      
    ctypesgen_path = 'ctypesgen/ctypesgen.py'                                       
    
    wrapper_filename = 'zlib.py'                                                 
    cmd = "LD_LIBRARY_PATH={} {} -I {} -L {} -l {} {} -o {}".format(             
    ZLIB_LIB_DIR, ctypesgen_path, ZLIB_INC_DIR, ZLIB_LIB_DIR, ZLIB_LIB,      
    ZLIB_HEADERS, wrapper_filename)                                        
    
    print(cmd)
    os.system(cmd)                                                             
    

    用法示例:
    python
    >>> import zlib
    >>> zlib.compress("asdfasdfasdfasdfasdf")
    'x\x9cK,NIKD\xc3\x00T\xfb\x08\x17'
    

    关于python - 可以围绕现有的大型C库自动生成Cython绑定(bind)吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31145163/

    相关文章:

    c - spawn() 函数(在 "spawn.h"中声明)从何而来?

    c - FFMPEG:将视频的一部分写入新文件时 AV 不同步

    python - 将字符串日期转换为纪元时间不适用于 Cython 和 POSIX C 库

    c++ - 使用 Cython 最大限度地提高性能

    python - 如何从类对象中区分python非类对象

    python - 在 Django 中设置多个同名的 cookie

    python - 传递 **kwargs 和尾随逗号的语法错误

    c - 堆 vs 堆栈 vs bss 部分

    python - Colab 中的 Cython : "cdef struct Rectangle" (line 9) identified as syntax error

    python - 如何使用正则表达式匹配字符串末尾的可选组?