0

我尝试获取结构数组中某个结构成员的地址,但我不想使用该成员的名称。

它应该是这样的:

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 中)。所以我尝试做一个函数,它需要模块数量和模块成员之一的索引,并返回适当成员的偏移量。

在返回之前是否有可能出现类似该行的内容?

4

2 回答 2

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];

注:offsetof定义在stddef.h. 有关更多信息,请参阅此Wikipedia 文章

如果您的编译器没有此功能,则一种实现offsetof可能是:

#define offsetof(st, m) \
     ((size_t) ( (char *)&((st *)0)->m - (char *)0 ))
于 2012-08-06T09:57:38.083 回答
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; 
} 
于 2012-08-06T10:40:58.043 回答