在C++中设置FourCC值

Nic*_*ick 5 c++ fourcc

我想在C++中设置一个FourCC值,即无符号4字节整数.

我想明显的方​​法是#define,例如

#define FOURCC(a,b,c,d) ( (uint32) (((d)<<24) | ((c)<<16) | ((b)<<8) | (a)) )
Run Code Online (Sandbox Code Playgroud)

然后:

uint32 id( FOURCC('b','l','a','h') );
Run Code Online (Sandbox Code Playgroud)

你能想到的最优雅的方式是什么?

Jam*_*kin 16

您可以使用以下命令使其成为编译时常量:

template <int a, int b, int c, int d>
struct FourCC
{
    static const unsigned int value = (((((d << 8) | c) << 8) | b) << 8) | a;
};

unsigned int id(FourCC<'a', 'b', 'c', 'd'>::value);
Run Code Online (Sandbox Code Playgroud)

通过一点额外的努力,您可以在编译时检查传入的每个数字是否在0到255之间.

  • @Dave:那是真的.这实际上只是一种避免宏而不失其优势的方法.其他回复建议内联函数不再给你一个编译时常量,这可能很方便.这提供了一些潜在的额外安全性,但是谁会把错误的东西放在FOURCC中呢?说实话,我确定自己是否会为此烦恼,但我想我会把它放在那里. (2认同)

San*_*a R 9

uint32_t FourCC = *((uint32_t*)"blah");
Run Code Online (Sandbox Code Playgroud)

为什么不呢?

编辑:int - > uint32_t.

并且它不会向uint32_t投射char**.它将(char*)转换为(uint32_t*),然后取消引用(uint32_t*).没有涉及endian-ness,因为它将uint32_t分配给uint32_t.唯一的缺陷是对齐,我没有明确指出32位类型.

  • 因为大端和小端机器的值不同。在某些体系结构上,这可能未对齐,从而导致运行时出现硬件异常。 (3认同)

Dou*_* T. 5

或者使用内联函数执行相同的操作

inline uint32_t FOURCC(uint8_t a, uint8_t b, uint8_t c, uint8_t d)
{
     return ( (uint32) (((d)<<24) | (uint32_t(c)<<16) | (uint32_t(b)<<8) | uint32_t(a)) )
} 
Run Code Online (Sandbox Code Playgroud)

并避免宏的头痛,但否则你的方法对我来说很好.


Max*_*axP 5

通过使用 C++11 constexpr,您可以编写如下内容:

constexpr uint32_t fourcc( char const p[5] )
{
    return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
}
Run Code Online (Sandbox Code Playgroud)

然后将其用作:

fourcc( "blah" );
Run Code Online (Sandbox Code Playgroud)

优点:

  • 更具可读性,
  • 如果字符串参数在编译时已知,则在编译时评估该函数(无运行时开销)。
  • 不依赖于字节序(即参数的第一个字符将始终位于 Fourcc 的最高有效字节中)。

缺点:

  • 需要 c++11(或更高版本)编译器。


Jar*_*Par 1

我认为你的算法没有任何问题。但对于这样的事情,我只会编写一个函数而不是宏。宏有很多隐藏的功能/问题,随着时间的推移,这些功能/问题可能会困扰您。

uint FourCC(char a, char b, char c, char d) { 
  return ( (uint32) (((d)<<24) | ((c)<<16) | ((b)<<8) | (a)) );
}
Run Code Online (Sandbox Code Playgroud)