CFFI 是从头文件解析 C 定义的合适工具吗

问题描述 投票:0回答:1

我想阅读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

我想念什么?你会如何做不同的事情?

python c cffi
1个回答
0
投票

我进步了!该文档没有帮助: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
感觉很难看

© www.soinside.com 2019 - 2024. All rights reserved.