如何让C++预处理器计算__LINE__算术值以实现WGL加载器函数自动绑定
解决方案
- 首先要明确:C标准里预处理器的
##令牌拼接操作发生在文本替换的早期阶段,而__LINE__ - 22 + 1这类整数算术运算属于编译期的常量计算,不会在预处理器文本替换阶段完成,所以你没法直接用原生预处理器实现「先算行号差值再拼接类型名」的逻辑。 - 最推荐的替代方案:修改宏定义,手动传入函数编号,完全规避对行号的依赖,兼容性最好也最不容易出错:
宏定义修改为:
调用示例:#define GetFuncDef(func_num, glFunc) _##glFunc = (f##func_num)GetProcAddress(#glFunc)
这种写法不受代码行增减的影响,即使后续在调用代码前加注释、空行或者其他逻辑也不需要修改参数。GetFuncDef(1, glFunc1); GetFuncDef(2, glFunc2); GetFuncDef(3, glFunc3); // 后续调用依次传入对应编号即可 - 如果一定要实现自动按行号生成编号,可以引入Boost.Preprocessor预处理器元编程库,它提供了预处理器阶段可执行的算术与拼接能力,写法如下:
注意该方案依赖Boost库,且依然存在行号依赖的脆弱问题:如果后续在首次调用宏的代码前新增了行,需要同步修改21这个常量值,非常容易出现类型不匹配的bug,不建议在生产环境使用。#include <boost/preprocessor/cat.hpp> #include <boost/preprocessor/arithmetic/sub.hpp> // 原逻辑__LINE__ -22 +1等价于__LINE__ -21,直接用预处理器减法宏实现 #define GetFuncDef(glFunc) _##glFunc = (BOOST_PP_CAT(f, BOOST_PP_SUB(__LINE__, 21)))GetProcAddress(#glFunc) - 额外优化方向:如果使用C11及以上标准,可以用
_Generic泛型选择器自动匹配函数指针类型,完全不需要手动维护fN类型编号与函数的对应关系,进一步降低出错概率。
内容的提问来源于stack exchange,提问作者Phillip
相关产品推荐
相关产品推荐

