[英]Accessing a member of a pointer (variable) struct within a struct
達成協議:我正在開發一個C函數,該函數配置包含許多成員的結構,例如* BASE(指向結構的指針),ID,MODE; 但是BASE是一個結構,根據接口的不同,可以將其定義為“結構a”,“結構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成員)。
更糟糕的是:當我嘗試編譯時,我在u32_t
typedef中的conflicting type qualifiers for 'u32_t'
錯誤和initialization from incompatible pointer type
near initialization for USART0_DEV.BASE
在每個interface_t
定義中near initialization for USART0_DEV.BASE
警告的near initialization for USART0_DEV.BASE
遇到conflicting type qualifiers for 'u32_t'
。
我在論壇上進行了搜索,但無法弄清楚我的錯誤。 這些幫助:
我的代碼有什么問題? 我該怎么辦才能使用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
錯誤中cast to union type from type not present in union
...
如果您想保持“開放”狀態,則應將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 = ...
...
}
您已將基本成員定義為u32_t上的指針,因此編譯器認為它所指向的是u32_t,而u32_t沒有名為US_IER的成員。 當您使用代碼的“工作”版本時,會發生什么事,即從uint_32 *到包含所需成員的AT91S_USART *的指針的隱式轉換。
BASE是u32_t pointer
類型的變量,並嘗試訪問u32_t pointer
實際上不可用的成員US_IER
。 但是,您可能無法實現將其定義為u32_t pointer
而不是structure pointer
期望,因為編譯器會期望如果通過struct指針訪問該成員,則應該已經定義了一個成員。
但是對於您的情況(即具有128種不同的接口類型),請定義具有這3個必需成員(在所有128個接口中通用)的結構類型US_IER, US_IAM, US_IDM
,並在該結構內定義具有必需可能成員的聯合,然后嘗試訪問這些成員帶開關盒或其他物品的物品。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.