用Cython访问C头文件中的魔法数字/标志
我想用Cython访问一些标准的C库,但这些库有很多标志。Cython的文档说我必须复制我需要的头文件部分。对于函数定义来说,这没问题,因为这些定义通常到处都有,文档里也有。但那些神秘的数字呢?
比如说,如果我想调用mmap
,我总能找到这个函数的定义,然后把它粘到一个.pxd文件里:
void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)
但是调用这个函数需要很多标志,比如PROT_READ
、MAP_ANONYMOUS
等等。我对此有两个问题:
首先,找到这些数字到底在哪里定义真是太麻烦了。其实我宁愿写一个.c文件,然后用printf打印出我需要的值。有没有更好的方法来找到某个标志的值,比如PROT_READ
?
其次,这些数字有多稳定?假设我提取了所有需要的值,并把它们硬编码到我的Cython源代码里,那么在不同的平台上编译时,PROT_READ
和PROT_EXEC
的值会不会互换?
即使答案是没有好的或合适的方法,我也想听听。我总是能接受某些事情很麻烦,只要我知道自己没有漏掉什么。
3 个回答
1
创建一个名为 foo.c 的文件,里面写入以下内容:
#include <sys/mman.h>
然后运行下面的命令:
cpp -dM foo.c | grep -v __ | awk '{if ($3) print $2, "=", $3}' > mman.py
这个命令会生成一个 Python 文件,里面定义了 mman.h 中的所有常量。
显然,如果你想的话,可以对多个包含文件这样操作。
生成的文件可能需要稍微整理一下,但基本上能满足你的需求。
6
要在Cython中使用这些常量,你不需要搞清楚它们到底来自哪里或者是什么,就像在C语言中一样。例如,你的.pxd文件可以这样写:
cdef extern from "foo.h":
void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)
cdef int PROT_READ
cdef int MAP_ANONYMOUS
...
只要这些定义是从foo.h文件中(直接或间接)包含进来的,这样就没问题了。