C++ 在缓冲区/数组中使用颜色结构

C++ 在缓冲区/数组中使用颜色结构,c++,arrays,struct,endianness,C++,Arrays,Struct,Endianness,我正在开发一个处理(以及其他)图像的库。为了与OGL的互操作性,我需要(至少)写入BGRA缓冲区(字节顺序->B优先) 为此,我正在设计一个ColorARGB类,它应该表示一种颜色。我想到了两种方法:第一种方法将颜色值存储为uint32\t,并提供字节缓冲区的转换方法;第二种方法将组件存储为字节,应该能够直接使用。代码: struct ColorARGB { uint32_t clrValue; ColorARGB(uint32_t clrValue):clrValue(clrV

我正在开发一个处理(以及其他)图像的库。为了与OGL的互操作性,我需要(至少)写入BGRA缓冲区(字节顺序->B优先)
为此,我正在设计一个ColorARGB类,它应该表示一种颜色。我想到了两种方法:第一种方法将颜色值存储为
uint32\t
,并提供字节缓冲区的转换方法;第二种方法将组件存储为字节,应该能够直接使用。代码:

struct ColorARGB
{
    uint32_t clrValue;
    ColorARGB(uint32_t clrValue):clrValue(clrValue){}
    ColorARGB(uint8_t a, uint8_t r, uint8_t g, uint8_t b)
    {
        clrValue = a << 24 | r << 16 | g << 8 | b;
    }
    static ColorARGB fromBGRA(const uint8_t* ptr)
    {
        return fromBGRA(reinterpret_cast<const uint32_t*>(ptr));
    }

    static ColorARGB fromBGRA(const uint32_t* ptr)
    {
        // This is little endian BGRA word format
        return ColorARGB(boost::endian::little_to_native(*ptr));
    }
    // Similar functions for toBGRA
}
第二个版本应该允许
std::vector
,而第一个版本会有问题,即在big-endian机器上,缓冲区是ARGB而不是BGRA。我也可以
重新解释_cast
,而
ColorARGB
由于结尾的原因无法解释

颜色argb2有什么问题吗?我是否会遇到可能的对齐问题,特别是在处理字节缓冲区(
uint8\u t*
)时?我可以简单地将比较实现为
reinterpret\u cast(&lhs)==reinterpret\u cast(&rhs)
,还是会因为对齐而失败

更新(不是真正的答案,但有帮助): 我在boost src代码中发现了以下用法:

#if defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86)
    // On x86 (which is little endian), unaligned loads are permitted
#   define RTTR_USE_UNALIGNED_ACCESS 1
#endif

理论上你可能会遇到对齐问题,但在实践中,我从未见过这种情况发生

还有第三个选项您没有列举,那就是通过使用联合来实现这两个。大致如下:

typedef union ARGBPixel {
    uint32_t colorValue;
    uint8_t components[4];  // <- Or an existing struct with separate a,r,g,b
} ARGBPixel;
typedef联合ARGBPixel{
uint32_t颜色值;

uint8_t components[4];//理论上,您可能会遇到对齐问题,但在实践中,我从未见过这种情况发生

还有第三个选项您没有列举,那就是通过使用联合来实现这两个目的。大致如下:

typedef union ARGBPixel {
    uint32_t colorValue;
    uint8_t components[4];  // <- Or an existing struct with separate a,r,g,b
} ARGBPixel;
typedef联合ARGBPixel{
uint32_t颜色值;

uint8_t components[4];//有趣的是,几天前我为一个SO答案编写了一个代码示例。它使用了一个简单的“颜色”键入以演示一个点。您可以。它使用一个并集为您提供选项1和一点选项2。您还应该知道,除非您将
uint32\u t
的地址从BGRA(uint8\t)传递到
,您将拥有UB。也就是说,如果您打算传入一个
uint8\u t
数组并将其别名为
uint32\u t
,您将违反严格的别名规则。这真的违反了严格的别名规则吗?因为我认为它只引用“函数的指针参数”。在这里,我只有一个参数。除了使用字符类型的左值或它自己的类型之外,任何对变量的访问都是官方未定义的行为。您可以使用
uint8\u t*
访问
uint32\u t
(假设它是无符号字符的别名),但您无法通过
uint32\u t*
访问最初的
uint\u t8
数组。因此,对于我的情况,什么是一个好的解决方案呢?根据这一点,甚至重新解释为
ColorARGB2
的转换将是UB。有趣的是,几天前我为So答案编写了一个代码示例。它使用了一个简单的“颜色”键入以演示一个点。您可以。它使用一个并集为您提供选项1和一点选项2。您还应该知道,除非您将
uint32\u t
的地址从BGRA(uint8\t)传递到
,您将拥有UB。也就是说,如果您打算传入一个
uint8\u t
数组并将其别名为
uint32\u t
,您将违反严格的别名规则。这真的违反了严格的别名规则吗?因为我认为它只引用“函数的指针参数”。在这里,我只有一个参数。除了使用字符类型的左值或它自己的类型之外,任何对变量的访问都是官方未定义的行为。您可以使用
uint8\u t*
访问
uint32\u t
(假设它是无符号字符的别名),但您无法通过
uint32\u t*
访问最初的
uint\u t8
数组。因此,对我的情况来说,什么是一个好的解决方案呢?根据这一点,即使重新解释为
ColorARGB2
也将是UB.AFAIK,您不应该阅读您尚未编写的工会成员的内容。我正在考虑这个问题,但我觉得这只会增加另一个失败点。好吧,你不应该读你没有写信给的工会会员的书。我在想这个,但我觉得这只会增加另一个失败点。