是否存在C函数签名数据库?如何自动生成适配Haskell FFI的签名表?
自动生成MicroHs风格的Haskell FFI C函数签名映射列表
你提到的MicroHs源码里定义了一套简化编码规则,用来标记Haskell FFI可调用的C函数签名,同时还维护了手动编写的函数映射表(比如log对应FFI_DD、fgetc对应FFI_Pi这类)。完全可以基于已编译C库或头文件自动生成这类列表,具体步骤如下:
一、先明确MicroHs的编码规则逻辑
先把源码里的编码规则拆解清楚,方便后续映射:
| 编码标识 | 返回值类型 | 参数列表 |
|---|---|---|
| V | void | 无参数 |
| i | int | 无参数 |
| I | value_t | 无参数 |
| IV | void | (value_t) |
| II | value_t | (value_t) |
| IIV | void | (value_t, value_t) |
| III | value_t | (value_t, value_t) |
| DD | flt_t | (flt_t) |
| Pi | int | (void*) |
| PI | value_t | (void*) |
| PP | void* | (void*) |
| iPi | int | (int, void*) |
| PPI | value_t | (void*, void*) |
| PPP | void* | (void*, void*) |
核心逻辑:编码 = 返回值类型的缩写 + 按顺序排列的每个参数类型缩写。比如int f(int, void*)的返回值是i,参数是i+P,所以编码为iPi。
二、提取C函数的完整签名信息
已编译的.so/.a/.dll库本身只存符号名,没有完整参数/返回值,所以需要结合头文件或调试信息提取:
- 基于头文件的AST分析:用Clang或GCC的AST导出功能,比如执行
clang -Xclang -ast-dump -fsyntax-only your_lib.h,可以得到头文件的抽象语法树,从中提取每个函数的返回值、参数类型和函数名。 - 结合库符号和调试信息:如果库带调试符号,用
objdump -W your_lib.so可以解析出带签名的函数信息,再提取所需内容。
三、自动映射编码并生成代码
写一个脚本(比如Python、Perl)完成以下步骤:
- 建立类型到缩写的映射表:
type_map = { "void": "V", "int": "i", "value_t": "I", "flt_t": "D", "void*": "P" } - 遍历提取到的每个函数签名:
- 把返回值类型转换成对应的缩写
- 把每个参数类型依次转换成缩写,拼接在返回值缩写后面
- 生成对应的
FFI_XXX宏(比如拼接结果是DD,就用FFI_DD)
- 输出MicroHs风格的函数映射代码行,比如:
{ "log", (funptr_t)log, FFI_DD }, { "fgetc", (funptr_t)fgetc, FFI_Pi },
四、需要注意的细节
- 可变参数函数(比如
printf)不在现有编码规则覆盖范围内,需要手动扩展规则或跳过。 - 遇到typedef定义的类型别名,要先解析成基础类型再映射缩写。
- 静态函数不会出现在库的符号表中,只能从源文件或头文件提取信息。
内容的提问来源于stack exchange,提问作者Janus Troelsen
相关产品推荐
相关产品推荐

