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内)をすばやく変更するには、それが必要です。そこで、モジュールの番号とモジュールメンバーの1つのインデックスを取り、適切なメンバーのオフセットを返す関数を実行しようとしました。

復帰前にそのようなセリフが出る可能性はありますか?

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ます。詳細については、このウィキペディアの記事を参照してください。

コンパイラにこれがない場合、次のような実装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 に答える