换一种说法: *.h/*.c --[??POSSIBLE??]--> *.pxd/*.pyx
好.我已经(我希望)在互联网上进行了足够的挖掘 - 但我认为这是一个很好的问题所以我会直截了当地问.
有一些相关的问题(例如,生成python绑定,使用什么方法/程序或在Python中包装C库:C,Cython或ctypes?)但是我不能总结我所问的情况也许是为了更"高级"的方法(特别是对于现有的库,而不是从python生成新的C).
在使用Cython之前,我已经掌握了一些经验.Cython对速度和可维护性赞不绝口.在我的书中可以使用小/单位代码 - 但是,这次我在我的板块上有更多...
遵循程序员的三大优点中的第一个 - 我希望尽可能少地完成这项工作.
所以真正的问题是如何通过.pxd和可能的.pyx文件的自动化方式来缓解创建(即节省时间而不是错误输入错误的东西).
这里似乎是关于如何做到这一点的唯一真实提示/注意事项 - 但是它上面的大多数项目都已经不存在了,旧的或者是sourceforge.许多似乎只适用于C++(这是我在这里做的).
还有人还在使用它们吗?最近?有没有人有这样的工作流程或最佳实践?我只是手动做得更好吗?
我的库由一组头文件很好地定义.一个包含所有C结构/类型的defs,另一个包含所有函数的原型.但它是loooonnnggg ...
谢谢你的任何提示.
更新(2015年8月25日):
是的,所以在过去的几个月里,当我有空余的时候,我试过:
CFFI(感谢@David指出这一点) - 有一个崇高的目标是"在不学习第三语言的情况下从Python调用C代码:现有的替代方案要求用户学习领域特定的语言(Cython,SWIG)或API(ctypes)" - 但它不太合适,因为它涉及到实际python文件中的相当程度的嵌入式C代码(或加载它).这对于一个大型库来说是一个非常手动的过程.也许我错过了一些东西......
SWIG是Python绑定的祖父,非常可靠.从根本上说,它并不像我理解的那样"放手" - 即你需要一个单独的规范文件.例如,您必须编辑所有C头文件以指示#define SWIG_FILE_WITH_INIT
使用或使用其他注释构建python模块.SIP在这里也有同样的问题.您不会从标头自动生成,您可以修改它们以包含您自己的指令和注释,并创建完整的规范文件.
cwrap - 我在Mac上,所以我用这个版本来铿锵.https://github.com/geggo/cwrap真的很差的文档 - 但是使用源代码我终于让它运行并生成了... 一个非常简单的结构头的空的.pyx文件.不太好.
xdress - 这表明了承诺.该网站已关闭,所以文档实际上似乎在这里.这里有大量的工作,看起来很简单.但是它需要所有的llvm头文件(以及一个正确链接的clang版本).我不得不使用brew install llvm —with-clang
.有一个xdress clang-3.5
分支,但它似乎没有完成足够的修复.我尝试为早期版本的clang(安装llvm33/llvm34)点击自制软件/版本并将其构建完成.无论如何,我离题了...它对一个简单的例子非常有用,但是完整库的结果ctypes文件非常混乱并且拒绝构建.AST C-> Python中的东西有点不对......
ctypesgen不是我在原始搜索中遇到的那个.文档很稀疏 - 或者你可以称之为简洁.在过去的4年中,它似乎也没有做过多少工作(如果开发人员要进一步推进该项目,那么人们会询问问题列表).我已经尝试过运行它,但遗憾的是它似乎与我怀疑/似乎与Clang编译器cdefs.h使用的问题有关_attribute_
.我尝试了类似-std=c11
但无济于事的事情.
总而言之,在我看过的所有内容中,我认为xdress最接近全自动生成的python绑定.它适用于给出的简单示例,但无法处理更复杂的现有库头,前向声明,枚举类型,void指针的所有复杂性 ......它似乎是一个设计良好且(有一段时间)维护良好的项目,因此,如果有人再次接受这些问题,可能会有一些方法来规避这些问题.
问题仍然存在,是否有人有一个强大的工具链来自动生成C头的python包装器?我觉得现实中是存在的总是要有点体力工作,并为CFFI看起来最"现代"的方式(最好的概述/比较我遇到的一个是在这里) -但它总是涉及专门编辑cdef()
的版本任何头文件(例如使用Python的CFFI并排除系统头文件).
小智 4
我发现 ctypesgen 非常适合自动生成。我只将它与一两个我希望开源的 python 模块一起使用,到目前为止我很高兴。这是一个将它与 zlib 一起使用的简单示例,但我也只是在其他一些库上成功尝试了它:(
编辑:我知道你提到 ctypesgen 在 mac 上有问题,所以也许需要有人调整它才能在 OSX 上工作 - 我家里没有 OSX,否则我会尝试一下。)
获取 ctypesgen:
git clone https://github.com/davidjamesca/ctypesgen.git
Run Code Online (Sandbox Code Playgroud)
运行简短的脚本来调用 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)
Run Code Online (Sandbox Code Playgroud)
使用示例:
python
>>> import zlib
>>> zlib.compress("asdfasdfasdfasdfasdf")
'x\x9cK,NIKD\xc3\x00T\xfb\x08\x17'
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1472 次 |
最近记录: |