问题描述
目标是创建一个包含3个字段的结构。这些字段之一必须是uint32_t union
,但是每个元素的标志都不同。我相信最好的方法是为每个外围设备创建一个单独的union
并将其分配给父结构中的void指针(以某种方式)。
当前计划:
//--------------Register for AAA
typedef union
{
struct
{
uint32_t spare : 32; //< Bits 0-31 not used
}Bits;
uint32_t FullData;
}ABC_EMPTY_DATA;
ABC_EMPTY_DATA AAA_Data;
//--------------Register for BBB
typedef union
{
struct
{
uint32_t use32BitColor : 1; //< Bit0
uint32_t enableTimer : 1; //< Bit1
uint32_t fooTheBar : 1; //< Bit2
uint32_t spare : 29; //< Bits 3-31 not used
}Bits;
uint32_t FullData;
}ABC_BBB_DATA;
ABC_EMPTY_DATA BBB_Data;
//--------------Register for CCC
typedef union
{
struct
{
uint32_t useInternalFrameTick : 1; //< Bit0
uint32_t useExternalFrameTick : 1; //< Bit1
uint32_t spare : 30; //< Bits 2-31 not used
}Bits;
uint32_t FullData;
}ABC_CCC_DATA;
ABC_CCC_DATA CCC_Data;
//-------The Peripherals with register element
typedef struct
{
char *Name;
unsigned int HexCmd;
void *Data; //Connect to corasponding XXXX_Data
}ABC_dataStructs;
//----- Initializing Peripherals
typedef struct
{
ABC_dataStructs AAA = {.Name = "AAA",.HexCmd = 0x00,.Data = (void*) &AAA_Data};
ABC_dataStructs BBB = {.Name = "BBB",.Data = (void*) &BBB_Data};
ABC_dataStructs CCC = {.Name = "CCC",.Data = (void*) &CCC_Data};
}ABC_CommandList;
void main(){
ABC_CommandList everything;
everything.CCC.FullData = 0x000F;
everything.BBB.use32BitColor = 0;
int myint = everything.AAA.HexCmd;
}
当前,我正在初始化struct中的值
ABC_dataStructs AAA = {.Name = "AAA",.Data = (void*) &AAA_Data};
无效
更重要的是,联合的分配没有按预期进行。当前结果仅允许everything.AAA.Data
,而无法分配/读取单个位。
为了避免出现“ XY问题”,我还试图解释软件的意图,如果我遇到了这种错误,或者您认为更好的话,请告诉我。谢谢。
注意:C struct,union pointer to struct还有另一种方法将structs
放在unions
中而不是unions
到structs
中,但这对我没有帮助将这些分配给void*
解决方法
初始化时遇到的问题是,您正在定义一个类型,并试图像同时将其作为变量一样对其进行初始化。您需要先定义该结构,然后初始化它的实例:
typedef struct
{
ABC_dataStructs AAA;
ABC_dataStructs BBB;
ABC_dataStructs CCC;
}ABC_CommandList;
void main(){
ABC_CommandList everything = {
.AAA = {.Name = "AAA",.HexCmd = 0x00,.Data = &AAA_Data},.BBB = {.Name = "BBB",.Data = &BBB_Data},.CCC = {.Name = "CCC",.Data = &CCC_Data},};
...
还请注意,不需要强制转换为void *
。
然后是这里的问题:
everything.CCC.FullData = 0x000F;
everything.BBB.use32BitColor = 0;
是CCC
和BBB
属于ABC_dataStructs
类型,并且该类型没有名为FullData
或use32BitColor
的字段。您需要将Data
成员强制转换为正确的指针类型,然后取消引用:
((ABC_CCC_DATA *)everything.CCC.Data)->FullData = 0x000F;
((ABC_BBB_DATA *)everything.BBB.Data)->use32BitColor = 0;
总而言之,有一种更好的方法来对这些数据进行建模。您真正想要的是3种寄存器类型的并集。然后ABC_dataStructs
将包含该联合以及单独的字段,该字段标记要使用的联合。
typedef struct
{
uint32_t spare : 32; //< Bits 0-31 not used
} ABC_EMPTY_DATA;
typedef struct
{
uint32_t use32BitColor : 1; //< Bit0
uint32_t enableTimer : 1; //< Bit1
uint32_t fooTheBar : 1; //< Bit2
uint32_t spare : 29; //< Bits 3-31 not used
} ABC_BBB_DATA;
typedef struct
{
uint32_t useInternalFrameTick : 1; //< Bit0
uint32_t useExternalFrameTick : 1; //< Bit1
uint32_t spare : 30; //< Bits 2-31 not used
} ABC_CCC_DATA;
typedef struct
{
char *Name;
unsigned int HexCmd;
union {
ABC_EMPTY_DATA AAA;
ABC_BBB_DATA BBB;
ABC_CCC_DATA CCC;
uint32_t FullData;
};
}ABC_dataStructs;
然后您可以定义以下内容:
ABC_CommandList everything = {
.AAA = {.Name = "AAA",.AAA = {}},.BBB = { .use32BitColor = 0 }},.FullData = 0x000F },};