c++ - 如何调用使用 token 粘贴的宏?

标签 c++ ffmpeg macros c-preprocessor token-pasting-operator

我正在尝试打印 ffmpeg C++ 中的版本程序。我在 /libavutil/version.h 中看到了有AV_VERSION它应该以 x.x.x 的格式告诉版本号.
作为测试,我使用了一些随机数作为函数参数,如下所示:std::string version = AV_VERSION(3,4,2); .如果我使用 LIBAVUTIL_VERSION_MAJOR,我会遇到同样的错误, LIBAVUTIL_VERSION_MINORLIBAVUTIL_VERSION_MICRO从文件中。那实际上是我第一次尝试打印版本号。
我得到的错误是 invalid suffix '.2' on floating constantinvalid suffix '.101' on floating constant如果我尝试打印 std::cout << AV_VERSION(LIBAVUTIL_VERSION_MAJOR,LIBAVUTIL_VERSION_MINOR,LIBAVUTIL_VERSION_MICRO) << std::endl;我明白预处理器认为 token 是 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++ 时,我很确定我会找到更多这种类型的宏,所以当我面对它们时,没有必要避免现在学习它们。
提前致谢!

最佳答案

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

#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
    

    关于c++ - 如何调用使用 token 粘贴的宏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70192113/

    相关文章:

    ffmpeg - 在 android(FFMPEG) 上构建编码器

    python - 如何使用 FFMPEG 选择文件的保存位置

    macros - 在 Common Lisp 中编写一个++ 宏

    c++ - 返回引用可以工作吗?

    c++ - 如何将 QDataWidgetMapper 与 QLineEdit 一起使用

    android - 在 Android NDK 中使用 Libavfilter 库实现多输入过滤器图

    c - 为什么有人会用未使用的参数/参数定义 C 宏?

    ios - 如何在 SWIFT 的 Objective-C 中替换 #define 宏?

    C++11 内存池类 - 从 void* 进行 static_casting 的解决方法?

    c++ - 从 std::istream 读取 SDL_RWops