我想阅读C头文件中描述的结构/数组/枚举的详细信息(我想获取已定义类型的列表、结构成员的列表和类型、枚举中定义的名称和值、数组的大小等.).
我不打算在 python 中使用 C 库,但我想使用经过实战测试的工具来“解析”C 定义,所以我选择了 CFFI 并尝试了以下操作:
从虚拟
test.h
文件开始
typedef struct {
int a;
int b[3];
float c;
} other_struct_T;
typedef struct {
bool i;
bool j;
other_struct_T k;
} main_struct_T;
预处理一次以确保解析#includes、#defines等。
gcc -E -P -xc test.h -o test.preprocessed.h
然后用 CFFI 加载它
from pathlib import Path
from cffi import FFI
u = FFI()
txt = Path("test.preprocessed.h").read_text()
u.cdef(txt)
k = u.typeof("main_struct_T")
print(k)
print(k.elements)
首先打印
<ctype 'main_struct_T'>
。
但在第二个失败了(k 似乎既不包含 .length,也不包含 .item,也不包含 .elements,正如人们对 ctype 实例所期望的那样......)
Traceback (most recent call last):
File "./parse_header.py", line 14, in <module>
print(k.elements)
^^^^^^^^^^^
AttributeError: elements
我想念什么?你会如何做不同的事情?
我进步了!该文档没有帮助:D 在返回的对象上使用
dir()
确实如此。
两个选项,最简单的一个是这个片段(正在进行中):
if k.kind == 'struct' :
for f in k.fields :
name, obj = f
print(name, obj.type, obj.offset)
其中
k
的获得完全按照问题中的解释。这给出:
i <ctype '_Bool'> 0
j <ctype '_Bool'> 1
k <ctype 'other_struct_T'> 4
递归可以用来挖掘
other_struct_T
另一个选项源自另一个问题(Using Python cffi for introspection)并导致此片段:
for k in u._parser._declarations :
v = u._parser._declarations[k][0]
if isinstance(v, cffi.model.EnumType) :
z[v.name] = list()
print(v.enumerators, v.enumvalues, v.get_c_name(), v.get_official_name())
for name, value in zip(v.enumerators, v.enumvalues) :
z[v.name].append((name, value))
elif isinstance(v, cffi.model.StructType) :
print(v.fldnames, v.fldtypes, v.fldquals, v.fldbitsize)
z[v.name] = list()
for name, ctype, qual, size in zip(v.fldnames, v.fldtypes, v.fldquals, v.fldbitsize) :
z[v.name].append((name, ctype, qual, size))
...
类不一样,方法和属性不一样...里面的信息应该是一样的,用起来
u._parser._declarations
感觉很难看