访问指针(可变)结构的成员的结构内(Accessing a member of a pointer

2019-10-29 05:40发布

这里的交易:我工作的一个C函数,配置包含许多成员结构,如* BASE(指向一个struct),ID,MODE; 但基础是可以被定义为(比方说)“结构一”,“结构B”,“...”,根据不同的接口的结构。 这是结构(和一些例子)声明:

typedef unsigned int u32_t;
typedef unsigned char u8_t;
typedef struct _interface_t{
    u32_t *BASE;
    u8_t ID;
    u32_t MODE;
} interface_t;

interface_t USART0_DEV  = {AT91C_BASE_US0, AT91C_ID_US0, 0}; // <-- Here we have a AT91C_BASE_US0 struct as *BASE
interface_t USART1_DEV  = {AT91C_BASE_US1, AT91C_ID_US1, 0};
interface_t TC0_DEV     = {AT91C_BASE_TC0, AT91C_ID_TC0, 0}; // <-- Here we have a AT91C_BASE_TC0 struct as *BASE
interface_t TC1_DEV     = {AT91C_BASE_TC1, AT91C_ID_TC1, 0};
interface_t TC2_DEV     = {AT91C_BASE_TC2, AT91C_ID_TC2, 0};
interface_t TWI_DEV     = {AT91C_BASE_TWI, AT91C_ID_TWI, 0}; // <-- Here we have a AT91C_BASE_TWI struct as *BASE

正如你看到的我用u32_t而不是结构的,因为我声明了一个指向结构。 后来我有我的函数定义为:

unsigned char ConfigureDevice(interface_t *Interface, u32_t config, u32_t Speed, u32_t IRQ_Trigger, void (*Interface_irq_handler)(void)){
    ...
    Interface->BASE->US_IER = IRQ_Trigger; //Note: US_IER Must receive a vector to a function
    ...
}

但我得到的错误“US_IER无法解析”。 所以,我想AT91S_USART InterfaceBASE = Interface->BASE; InterfaceBASE->US_IER = IRQ_Trigger; AT91S_USART InterfaceBASE = Interface->BASE; InterfaceBASE->US_IER = IRQ_Trigger; 代替的Interface->BASE->US_IER = IRQ_Trigger; 并没有得到错误。 但我不能用这个,因为我总是不知道我在处理什么样的接口(直到我读ID件)。

它会变得最糟糕的:当我尝试编译我不断收到conflicting type qualifiers for 'u32_t'错误u32_t的typedef和initialization from incompatible pointer type ,并near initialization for USART0_DEV.BASE各的警告interface_t定义。

我搜索的论坛,但我想不出我的错误(或多个)进行。 这些那些有点帮助:

  • 创建结构内结构
  • typedef结构中定义结构

这有什么错我的代码? 我能做些什么来使用类似Interface->BASE->US_IER

编辑:你好!所以现在这是我的了:

typedef struct _Interface_t{
    struct PERIPH_BASE * BASE;
    u32_t ID;
    u32_t MODE;
Interface_t;

Interface_t USART0_DEV  = {(struct PERIPH_BASE *)AT91C_BASE_US0, AT91C_ID_US0, 0};
...
unsigned char ConfigureDevice(Interface_t *Interface, u32_t config, u32_t Speed, u32_t IRQ_Trigger,...
...
((AT91S_SYS)Interface->BASE)->AIC_IECR = IRQ_Trigger; //No problems marked by Eclipse Code Editor
....

}

看起来不错,但在编译的时候我被cast to union type from type not present in union错误...

Answer 1:

BASE是一个类型的变量u32_t pointer ,并试图访问一个成员US_IER这是不是真的在提供u32_t pointer 。 但是,你有这个定义为的期望u32_t pointer ,而不是structure pointer是不可能的,因为编译器会期望一个成员都应该如果通过一个结构指针访问已经确定。

但是,对于你的情况(即,具有128个不同接口类型),定义与这些3个所需成员的结构类型(在所有128个接口常见) US_IER, US_IAM, US_IDM以及与可能需要的成员结构内定义一个联盟,并尝试访问这些项目有开关的情况下,或者别的。



Answer 2:

如果你想保持“开放”,您应该定义BASE作为

void *BASE;

或者,为了发信号/文件,这是一个特殊的指针,就可以使用一个不完整的类型:

struct hwbase * BASE;

并把它定义为

interface_t USART0_DEV  = {AT91C_BASE_US0, AT91C_ID_US0, 0};

如果使用void *或者更确切地说

interface_t USART0_DEV  = {(struct hwbase *)AT91C_BASE_US0, AT91C_ID_US0, 0};

对于第二个选项。

然后,在使用它,你已经确定你的权利类型的硬件(例如,TWI,USART)操作之后,你可以投。

从上述投你的指针向右类型,如

unsigned char ConfigureDevice(interface_t *Interface, u32_t config, u32_t Speed, u32_t IRQ_Trigger, void (*Interface_irq_handler)(void)){
    ...
    ((AT91S_USART *)Interface->BASE)->US_IER = IRQ_Trigger; //Note: US_IER Must receive a vector to a function
    ...
}

(在这里我不知道,如果AT91S_USART已经是一个指针类型-在这种情况下,你忽略了* )。

另一种选择可能是为了增加一些函数指针有一种“穷人的OOP”的:

typedef void config_func(struct _interface_t *, whateveryouneed...)

config_func config_usart; // forward declaration, does as well ensire you have no typo in the function
typedef struct _interface_t{
    void *BASE;
    u8_t ID;
    u32_t MODE;
    config_func * configure; // function pointer
} interface_t;

interface_t USART0_DEV  = {AT91C_BASE_US0, AT91C_ID_US0, 0, config_usart };

void config_usart(struct _interface_t * iface, whateveryouneed...)
{
    AT91S_USART * my_base = iface->BASE;
    ...
    my_base->US_IER = ...
    ...
}


Answer 3:

您已经定义了你的基地成员作为一个u32_t指针,以便编译器认为什么是它指出是u32_t和u32_t没有一个名为US_IER成员。 当您使用“工作”版本的你的代码是从uint_32指针*到AT91S_USART *,它包含了所需部件的隐式转换,会发生什么。



文章来源: Accessing a member of a pointer (variable) struct within a struct