换句话说:*.h/*.c --[??POSSIBLE??]--> *.pxd/*.pyx
好。我已经做完了(希望)在Internet上进行了足够的挖掘-但是我认为这是一个好问题,所以我将直接询问。
有一些相关的问题(例如Generate python bindings, what methods/programs to use或Wrapping 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日):
是的,所以在过去的几个月里,我有空的时候尝试了:
#define SWIG_FILE_WITH_INIT
构建python模块或使用其他注释。 SIP在这里有同样的问题。您不会从 header 中自动生成,而是对其进行修改以包括您自己的指令和注释,并创建一个完整的规范文件。 brew install llvm —with-clang
。有一个xdress clang-3.5
分支,但似乎没有完成足够的修复。我尝试点击自制软件/版本以获取早期版本的clang(安装llvm33 / llvm34),并建立了它。无论如何,我离开了……对于一个简单的例子来说,它工作得很好,但是整个库所产生的ctypes文件很乱,因此拒绝构建。 AST C-> Python中的内容有些错误... _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/