如何调用使用标记粘贴的宏?

How to call macro that uses token pasting?

我正在尝试在 C++ 程序中打印 ffmpeg 版本。我看到 /libavutil/version.h 中有 AV_VERSION 应该以 x.x.x.

格式告诉版本号

作为测试,我使用了一些随机数作为函数参数,如下所示:std::string version = AV_VERSION(3,4,2);。如果我使用文件中的 LIBAVUTIL_VERSION_MAJORLIBAVUTIL_VERSION_MINORLIBAVUTIL_VERSION_MICRO,我会得到同样的错误。那实际上是我第一次尝试打印版本号。

如果我尝试打印 std::cout << AV_VERSION(LIBAVUTIL_VERSION_MAJOR,LIBAVUTIL_VERSION_MINOR,LIBAVUTIL_VERSION_MICRO) << std::endl;

,我得到的错误是 invalid suffix '.2' on floating constantinvalid suffix '.101' on floating constant

我知道预处理器认为令牌是 float,因此出现错误。你是如何使用这种宏功能的?

那个宏在我上面提到的文件中,所以它一定是一种调用那个宏函数而不报错的方法,认为这是一个成熟的库,我猜其他库也使用类似的东西来打印版本号.

下面是AV_VERSION在头文件中的定义以及我的调用方式:

 #define AV_VERSION_INT(a, b, c) ((a)<<16 | (b)<<8 | (c))
 #define AV_VERSION_DOT(a, b, c) a ##.## b ##.## c
 #define AV_VERSION(a, b, c) AV_VERSION_DOT(a, b, c)

 #define AV_VERSION_MAJOR(a) ((a) >> 16)
 #define AV_VERSION_MINOR(a) (((a) & 0x00FF00) >> 8)
 #define AV_VERSION_MICRO(a) ((a) & 0xFF)

 #define LIBAVUTIL_VERSION_MAJOR  57
 #define LIBAVUTIL_VERSION_MINOR   9
 #define LIBAVUTIL_VERSION_MICRO 101

 #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
                                            LIBAVUTIL_VERSION_MINOR, \
                                            LIBAVUTIL_VERSION_MICRO)
 #define LIBAVUTIL_VERSION       AV_VERSION(LIBAVUTIL_VERSION_MAJOR,     \
                                        LIBAVUTIL_VERSION_MINOR,     \
                                        LIBAVUTIL_VERSION_MICRO)

 int main()
 {
     std::string version = AV_VERSION(3,4,2);
     std::cout << AV_VERSION(LIBAVUTIL_VERSION_MAJOR,LIBAVUTIL_VERSION_MINOR,LIBAVUTIL_VERSION_MICRO) << std::endl;

     return 0;
 }

我本可以跳过这个错误,但在我尝试学习 C++ 时,我很确定我会找到更多此类宏,所以现在面对它们时没有必要避免学习它们。

提前致谢!

您需要使用 stringize 扩展。由于预处理器的工作方式,这涉及到两个宏:

#define STR(x) #x
#define XSTR(x) STR(x)

STR 将采用您提供的任何参数并将其变为字符串文字。

XSTR会先展开它的参数x,结果就是STR的参数。

举例说明:

  • STR(LIBAVUTIL_VERSION) 会给出 "LIBAVUTIL_VERSION"
  • XSTR(LIBAVUTIL_VERSION) 会给出 "57.9.101"

根据您的代码演示:

int main()
{
    std::string version1 = XSTR(LIBAVUTIL_VERSION);
    std::string version2 = XSTR(AV_VERSION(3,4,2));
    std::cout << version1 << "\n";
    std::cout << version2 << "\n";
    return 0;
}

输出:

57.9.101
3.4.2