0

I try to get the address of some struct member in array of structures but i don't want to use name of that member.

It should be something like this:

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

I need that for quick modification of configuration (in EEPROM) which is in different structs. So I try to do function which takes number of module and index of one of the module member and returns offset of for proper member.

If there is any possibility for something like that line before return?

2
  • You do not want to use the name of the member, but ulMember instead, do I understand that correctly? I see only 2 ways: 1) map ulMember to the appropriate member through something like a switch statment and 2) hardcode the offset. Commented Aug 6, 2012 at 9:54
  • You are correct. I want some kind of index instead of name. Commented Aug 6, 2012 at 10:37

2 Answers 2

3

You could do it by using a helper array, using 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;
}

Note that your formula could be simplified as:

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

Or even further:

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

Note: offsetof is defined in stddef.h. See this Wikipedia article for more.

If your compiler doesn't have this, one implementation of offsetof could be:

#define offsetof(st, m) \
     ((size_t) ( (char *)&((st *)0)->m - (char *)0 ))
Sign up to request clarification or add additional context in comments.

1 Comment

That function "offsets" must be based on offsetof()? My compiler had some problem with offsetof() (I'm using IAR for ARM).
0

We can use the below logic also to find the offset of each memebers of a structure and then we can directly add it to the base addres of the particular instance of the structure variable.

#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; 
} 

2 Comments

1) most people like preprocessor macro names in ALLCAPS. 2) The compiler likes statements to be terminated by a semicolon. 3) the solution from Shahbaz is better, and more complete. 4) a few break statements inside the switch will avoid the value for the last menber to be returned for every value of ulMember. 5) size_t seems a natural type for an offset.
@wildplasser Fixed the TYPO mistakes

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.