2012-08-06 4 views
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에) 구성의 빠른 수정합니다. 그래서 모듈 구성원 중 하나의 모듈과 인덱스의 번호를 취하고 적절한 멤버에 대한 오프셋을 반환하는 함수를 만들려고합니다.

돌아 오기 전에 해당 줄이있을 가능성이 있다면?

+0

회원의 이름은 사용하고 싶지 않지만 ulMember 대신 올바르게 이해합니까? 나는 단지 2 가지 방법을 본다. 1) switch statment와 같은 것을 통해 적절한 멤버에게 ul 회원을 매핑하고 2) 오프셋을 하드 코드한다. –

+0

정확합니다. 나는 이름 대신에 어떤 종류의 색인을 원한다. – bienieck

답변

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) switch 내부의 몇 가지'break' 문은 ulMember의 모든 값에 대해 마지막 menber가 리턴되는 값을 피할 것입니다. 5) size_t는 오프셋을위한 자연스러운 형식입니다. – wildplasser

+0

@wildplasser TYPO 실수를 수정했습니다. – rashok

3

당신은 offsetof를 사용하여, 헬퍼 배열을 사용하여 그것을 할 수 : 더욱

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

또는 :

Address = ulModule * sizeof(tModule) + offsets[ulMember]; 
수식과 같이 간단하게 할 수

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


참고 : offsetofstddef.h에 정의됩니다. 자세한 내용은 Wikipedia article을 참조하십시오. 컴파일러이없는 경우

, offsetof 중 하나 구현 될 수있다 :

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

"offset"함수는 offsetof()를 기반으로해야합니까? 내 컴파일러는 offsetof() (ARM 용 IAR을 사용하고 있습니다)에 문제가있었습니다. – bienieck

+0

@ user1578827, 내 업데이트 – Shahbaz

관련 문제