You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何仅用C预处理器提取头文件函数名至boost.preprocessor结构

纯C预处理器提取被宏包裹的函数名至Boost.Preprocessor兼容结构

核心思路

针对FOO [返回类型] BAR 函数名(参数);的固定格式,利用C预处理器的参数拆分特性,剥离FOO和BAR标记,提取函数名,再将收集到的函数名组织成Boost.Preprocessor支持的序列/元组格式。

步骤1:单个函数名提取宏

定义宏拆分函数声明,精准提取函数名:

// 拆解函数声明,提取函数名
#define EXTRACT_SINGLE_FUNC(decl) _EXTRACT_HELPER(decl)
#define _EXTRACT_HELPER(foo, ret_type, bar, func_name, ...) func_name

// 测试示例
#define TEST_F1 EXTRACT_SINGLE_FUNC(FOO int * BAR f(long, double))
#define TEST_F2 EXTRACT_SINGLE_FUNC(FOO void BAR g())
// TEST_F1 展开为 f,TEST_F2 展开为 g

步骤2:组织成Boost.Preprocessor兼容结构

生成逗号分隔序列(如(f, g))

通过宏收集函数名,生成符合Boost.Preprocessor序列要求的格式:

// 定义序列构建宏
#define SEQ_START()
#define SEQ_ADD(seq, func) seq, func
#define SEQ_FINALIZE(seq) (seq)

// 构建函数名序列
#define MY_FUNC_SEQ \
SEQ_FINALIZE( \
    SEQ_ADD( \
        SEQ_ADD(SEQ_START(), EXTRACT_SINGLE_FUNC(FOO int * BAR f(long, double))), \
        EXTRACT_SINGLE_FUNC(FOO void BAR g()) \
    ) \
)
// MY_FUNC_SEQ 最终展开为 (f, g)

生成嵌套元组(如(f)(g))

如果需要这种格式,调整构建宏即可:

#define TUPLE_START()
#define TUPLE_ADD(tuple, func) tuple(func)
#define TUPLE_FINALIZE(tuple) tuple

#define MY_FUNC_TUPLES \
TUPLE_FINALIZE( \
    TUPLE_ADD( \
        TUPLE_ADD(TUPLE_START(), EXTRACT_SINGLE_FUNC(FOO int * BAR f(long, double))), \
        EXTRACT_SINGLE_FUNC(FOO void BAR g()) \
    ) \
)
// MY_FUNC_TUPLES 最终展开为 (f)(g)

步骤3:函数名转字符串字面量

结合Boost.Preprocessor迭代,将序列中的函数名转为字符串:

#include <boost/preprocessor/seq/for_each.hpp>

// 字符串化宏
#define STRINGIFY(x) #x
#define FUNC_TO_STR(func) STRINGIFY(func)

// 迭代处理序列中的每个函数名
#define PRINT_FUNC(r, _, func) puts(FUNC_TO_STR(func));

// 调用迭代
BOOST_PP_SEQ_FOR_EACH(PRINT_FUNC, _, MY_FUNC_SEQ)

注意事项

  • 若原头文件包含大量函数声明,手动枚举较繁琐,但纯C预处理器无法自动过滤非函数声明(如枚举、结构体),需手动筛选目标函数声明传入宏。
  • 确保FOO和BAR未被其他代码重定义,若有冲突可临时重命名标记宏后再处理。

内容的提问来源于stack exchange,提问作者SuibianP

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 01:39:32