2012-08-06 24 views
0

我嘗試獲取結構數組中某個struct成員的地址,但我不想使用該成員的名稱。如何獲得結構數組中某個struct成員的地址

應該是這樣的:

typedef struct{    
    unsigned char MrChar; 
    unsigned short MrShort; 
    unsigned long MrLong; 
    unsigned char MrArray[5]; 
}tModule; 

static tModule taModulesArray[MODULES_AMOUNT] = { // MODULES_AMOUNT = 2 
    {0x22, 0x3298, 0x92324583, "djsoe"}, // Module 1 
    {0x33, 0x1843, 0x65644113, "gskwc"}, // Module 2 
}; 

unsigned long usGetMemberAddr(unsigned long ulModule, unsigned long ulMember){ 
    unsigned long Address; 
    Address = abs(taModulesArray_BaseAddress - taModulesArray[ulModule].[ulMember]); 
    return Address; 
} 

我需要的配置(EEPROM)的快速修改是在不同的結構。所以我試着做一些帶有模塊成員的模塊和索引號的函數,並返回適當成員的偏移量。

如果在返回之前有類似該行的可能性?

+0

你不想使用成員的名字,而是使用ulMember,我是否理解正確?我只看到2種方法:1)通過類似開關的統計信息將ulMember映射到相應的成員; 2)對偏移進行硬編碼。 – 2012-08-06 09:54:59

+0

你是對的。我想要一些索引而不是名字。 – bienieck 2012-08-06 10:37:07

回答

0

我們可以使用下面的邏輯也找到了結構的每個承包商,客人的偏移量,然後我們就可以直接添加它到結構變量特定實例的基地址。

#define OFFSET(type, member) ((int) (& (((type *)(0))->member))) 

int find_offset(unsigned long ulMember) 
{ 
    unsigned long off = 0; 

    switch(ulMember) 
    { 
     case 1: 
      off = OFFSET(tModule, MrChar); 
      break; 
     case 2: 
      off = OFFSET(tModule, MrShorc); 
      break; 
     case 3: 
      off = OFFSET(tModule, MrLong); 
      break; 
     case 4: 
      off = OFFSET(tModule, MrArray); 
      break; 
    } 

    return off; 
} 

unsigned long usGetMemberAddr(unsigned long ulModule, unsigned long ulMember) 
{ 
    unsigned long Address; 

    Address = (unsigned long)&taModulesArray[ulModule] + find_offset(ulMember); 

    return Address; 
} 
+0

1)大多數人喜歡ALLCAPS中的預處理器宏名稱。 2)編譯器喜歡用分號結尾的語句。 3)Shahbaz的解決方案更好,更完整。 4)交換機內部的一些'break'語句將避免每個ulMember的值返回最後一個menber的值。 5)size_t似乎是一個偏移量的自然類型。 – wildplasser 2012-08-06 11:28:23

+0

@wildplasser修正了TYPO的錯誤 – rashok 2012-08-06 11:30:41

3

您可以通過使用輔助陣列做到這一點,利用offsetof

typedef struct{    
    unsigned char MrChar; 
    unsigned short MrShort; 
    unsigned long MrLong; 
    unsigned char MrArray[5]; 
}tModule; 

size_t offsets[] = { 
    offsetof(tModule, MrChar), 
    offsetof(tModule, MrShort), 
    offsetof(tModule, MrLong), 
    offsetof(tModule, MrArray) 
}; 

unsigned long usGetMemberAddr(unsigned long ulModule, unsigned long ulMember){ 
    unsigned long Address; 
    Address = abs((char *)&taModulesArray   // base of taModulesArray 
      - ((char *)&taModulesArray[ulModule] // start of this module 
       + offsets[ulMember]));    // + offset of member 
    return Address; 
} 

請注意,您的公式可以簡化爲:

Address = (char *)&taModulesArray[ulModule] 
      - (char *)&taModulesArray 
      + offsets[ulMember]; 

甚至更​​遠:

Address = ulModule * sizeof(tModule) + offsets[ulMember]; 

備註:offsetofstddef.h中定義。有關更多信息,請參閱此Wikipedia article

如果你的編譯器不具備這一點,實施offsetof可能是:

#define offsetof(st, m) \ 
    ((size_t) ((char *)&((st *)0)->m - (char *)0)) 
+0

該函數「偏移」必須基於offsetof()?我的編譯器在offsetof()方面有一些問題(我正在使用ARM的IAR)。 – bienieck 2012-08-06 10:41:37

+0

@ user1578827,請參閱我的更新 – Shahbaz 2012-08-06 11:52:06

相關問題