如何调用使用标记粘贴的宏?
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_MAJOR
、LIBAVUTIL_VERSION_MINOR
和 LIBAVUTIL_VERSION_MICRO
,我会得到同样的错误。那实际上是我第一次尝试打印版本号。
如果我尝试打印 std::cout << AV_VERSION(LIBAVUTIL_VERSION_MAJOR,LIBAVUTIL_VERSION_MINOR,LIBAVUTIL_VERSION_MICRO) << std::endl;
,我得到的错误是 invalid suffix '.2' on floating constant
或 invalid 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
我正在尝试在 C++
程序中打印 ffmpeg
版本。我看到 /libavutil/version.h
中有 AV_VERSION
应该以 x.x.x
.
作为测试,我使用了一些随机数作为函数参数,如下所示:std::string version = AV_VERSION(3,4,2);
。如果我使用文件中的 LIBAVUTIL_VERSION_MAJOR
、LIBAVUTIL_VERSION_MINOR
和 LIBAVUTIL_VERSION_MICRO
,我会得到同样的错误。那实际上是我第一次尝试打印版本号。
如果我尝试打印 std::cout << AV_VERSION(LIBAVUTIL_VERSION_MAJOR,LIBAVUTIL_VERSION_MINOR,LIBAVUTIL_VERSION_MICRO) << std::endl;
invalid suffix '.2' on floating constant
或 invalid 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