我不知道如何破译这个人需要告诉我发生了什么请帮助
typedef struct _ARGBCOLOR {
union {
struct {
BYTE B;
BYTE G;
BYTE R;
BYTE A;
};
DWORD ARGB;
};
} ARGBCOLOR, *PARGBCOLOR;
如果您有 ,ARGBCOLOR x;
您可以访问 4 个单独的字节作为x.B
、x.G
、x.R
和x.A
,或访问 32 位字作为x.ARGB
。
C标准保证这些将正确覆盖(假设尺寸适合和填充要求不会拧紧狗(不是这里的情况))。但是这个结构显然假设了一个小端系统。
一个额外的复杂因素是工会是匿名的。像这样命名一个联合是很常见的u
,但是一些编译器允许内部联合和结构是匿名的,因此它的成员被访问就好像它们在一个级别上(与联合本身处于同一级别)。
我最喜欢做这种覆盖类型的方法是将联合放在最外层。您可以复制kind
ortype
成员,以便在任何地方都可以访问它。但是这种方式消除了使用匿名联合的诱惑(在 Ansi-C 或 C99 中不可用),因为您不需要u
中间的虚假成员。
typedef union _ARGBCOLOR {
//BYTE type;
struct {
//BYTE type;
BYTE B;
BYTE G;
BYTE R;
BYTE A;
} bytes;
struct {
//BYTE type;
DWORD ARGB;
} word;
} ARGBCOLOR, *PARGBCOLOR;
由于共同的初始前缀属性,所有三个BYTE type;
成员将覆盖相同的内存。
另一个变体是为单个字节创建一个数组。
typedef union _ARGBCOLOR {
DWORD dword;
BYTE byte[ sizeof(DWORD)/sizeof(BYTE) ];
} ARGBCOLOR, *PARGBCOLOR;
enum { B,G,R,A };
现在我们不需要两个级别,并且类型双关更明显。
ARGBCOLOR x = { 0x10203040 };
x.byte[B] = 50;
x.byte[G] = 60;
printf("0x%8x\n", x.dword); // prints: 0x10206050
它与在联合之外声明结构所做的事情相同,但允许您匿名进行,将结构的成员公开为与其他联合成员相同的范围。您的构造特别允许您执行类似的操作
ARGBCOLOR a;
printf("a = %u.%u.%u.%u or %lu\n", a.B, a.G, a.R, a.A, a.ARGB);
(联合本身让您可以将其视为联合中的一种类型,在这种情况下,您可以将其视为四个 BYTE 值的序列或单个 DWORD 值)
如果您将结构定义提升到联合之外:
struct ARGB_VALUES {
BYTE B, G, R, A;
};
struct ARGBCOLOR {
union {
ARGB_VALUES VALUES; /* My god, how can you tell a type from a member? */
DWORD ARGB;
};
};
以前的 printf 必须是:
ARGBCOLOR a;
printf("a = %u.%u.%u.%u or %lu\n", a.VALUES.B, a.VALUES.G, a.VALUES.R, a.VALUES.A, a.ARGB);
注意:您使用的结构定义构造非常陈旧。您可以按如下方式减少它并保存为每个结构/类提供第二个别名,该别名会使您的符号表膨胀:
typedef struct ARGBCOLOR {
...
} *PARGBCOLOR;
你这样做的方式相当于:
struct _ARGBCOLOR {}; // First symbol.
typedef _ARGBCOLOR ARGBCOLOR;
typedef _ARGBCOLOR *PARGBCOLOR;
typedef struct _ARGBCOLOR
{
union
{
struct
{
BYTE B;
BYTE G;
BYTE R;
BYTE A;
};
DWORD ARGB;
};
} ARGBCOLOR, *PARGBCOLOR;
如果你仔细观察,你可以在中看到 astruct
和 a 。您可以使用 typedefed struct中的任何一个,无论哪个可用DWORD
union
ARGBCOLOR
最外面的结构在您的示例中并没有真正有用,但是当它有一个额外的成员称为kind
或类似的成员时:
struct ARGBCOLOR {
uint8_t kind;
union {
struct {
BYTE B;
BYTE G;
BYTE R;
BYTE A;
};
DWORD ARGB;
};
} ARGBCOLOR;
然后根据kind
您的值将联合解释为具有成员B
、和的结构G
,或DWORD 。R
A
ARGB
编辑:请记住,联合和内部结构等匿名成员仅成为 C11 中 C 标准的一部分。
在联合中,每个数据成员都从内存中的相同位置开始。与 4个字节DWORD ARGB
共享内存位置。因此,联合的大小将为 4 个字节,您可以使用, , , 或(可以修改单个字节而不影响其他字节)struct
作为一个整体使用ARGB
或逐字节访问它。A
R
G
B