如何调用使用令牌粘贴的宏?解决C++调用FFmpeg AV_VERSION宏报错问题
问题原因
你遇到的编译错误本质是AV_VERSION宏的输出不是字符串字面量,而是未经字符串化的版本号字面量。从给出的宏定义可以看到AV_VERSION本质是调用AV_VERSION_DOT,通过##预处理器运算符将三个参数拼接为a.b.c格式的令牌,比如AV_VERSION(3,4,2)展开后会得到3.4.2,这在C++语法中不属于合法的整数、浮点数或者字符串字面量,编译器会将其识别为非法的浮点数后缀,因此报错。
正确使用方法
这类拼接生成版本号的宏,必须配合预处理器字符串化宏使用才能得到合法的字符串字面量。
首先你需要先定义两层字符串化宏:
#define STRINGIFY(x) #x #define TOSTRING(x) STRINGIFY(x)
这里用两层宏的原因是:直接使用#x操作符不会展开x内部的宏定义,只有外层套一层宏,才能先把AV_VERSION的输出展开为a.b.c格式后再字符串化。
然后修改你的调用代码为:
// 测试自定义版本号 std::string version = TOSTRING(AV_VERSION(3,4,2)); // 打印libavutil版本号,可直接使用FFmpeg预定义的LIBAVUTIL_VERSION宏,无需手动传参数 std::cout << TOSTRING(LIBAVUTIL_VERSION) << std::endl;
这样预处理器处理后,TOSTRING(AV_VERSION(3,4,2))会被展开为"3.4.2"的合法字符串字面量,可直接用于赋值或者输出。
可选替代方案(不使用字符串化宏)
如果你不想处理预处理器宏的展开逻辑,也可以直接用整数版本号API自己拼接字符串:
int ver = LIBAVUTIL_VERSION_INT; std::string version = std::to_string(AV_VERSION_MAJOR(ver)) + "." + std::to_string(AV_VERSION_MINOR(ver)) + "." + std::to_string(AV_VERSION_MICRO(ver)); std::cout << version << std::endl;
这种写法是纯C++语法,不需要依赖预处理器的字符串化规则,可读性更高。
内容的提问来源于stack exchange,提问作者s_diaconu
相关产品推荐
相关产品推荐

