2010-03-25 5 views
3

C faqs가 방법으로 설명합니다. here is the link.런타임에 이름으로 구조 필드에 액세스하려면 어떻게해야합니까?

하지만 이해할 수 없지만 누군가 나를 설명 할 수 있습니까? 아니면 다른 방법을 줘?

감사합니다.

+0

A는 괜찮습니다. Q는 sux입니다. 구글 "자바 반영", C 언어는 그것을 지원하지 않습니다. –

+0

나는 반사를 알고, C는 점프지도, 자바 리플렉션을 통해 그것을 지원하고, 내 질문의 동등하지 않습니다,하지만 여전히 고마워. – drigoSkalWalker

답변

5

나는이 예제는 명확한 답을하게 생각 : 당신이 당신의 바이너리 디버그 정보를 컴파일하는 경우

struct test 
{ 
    int b; 
    int a; 
}; 

int main() 
{ 
    test t; 
    test* structp = &t; 

    //Find the byte offset of 'a' within the structure 
    int offsetf = offsetof(test, a); 

    //Set the value of 'a' using pointer arithmetic 
    *(int *)((char *)structp + offsetf) = 5; 

    return 0; 

} 
+0

"name"(a)는 "런타임에"발견되는 것이 아니라 컴파일 타임의 심볼임을 지적 할 가치가 있다고 생각합니다. 후자의 경우 문자열이어야하고 offsetof()는 작동하지 않습니다. – unwind

1

당신은 일종의 이름 검색을 직접 구현할 수 없습니다.

C에는 프로그램을 실행할 때 남겨진 이름 정보가 없습니다.

일반적으로 다른 구조체 필드 유형에 대해이를 지원하는 작업은 복잡합니다.

1

, 당신은 런타임에 이름을 조회하는 데 사용할 수 있습니다. 예를 들어 gcc (일반적으로)은 DWARF 형식의 디버그 정보를 생성하며 libdwarf을 사용하여 디버그 정보를 처리 할 수 ​​있습니다.

DWARF의 경우 DW_TAG_member 노드에서 필드를 찾을 수 있습니다. DW_AT_data_member_location 속성은 컴파일시 offsetof()에서와 마찬가지로 필드의 오프셋을 제공합니다.

0

offsetof() 매크로를 사용하여 계산 된 필드 오프셋을 추적하십시오. structp이 구조체의 인스턴스에 대한 포인터이며, 필드 F는 offsetb를 갖는 INT 경우 구조가 struct {...} 정의를 사용하여 정의되는 경우, F의 값은

*(int *)((char *)structp + offsetf) = value; 
0

간접적으로 설정할 수있는, 그 어렵다 실행 파일에 회원 이름과 관련된 정보가 있습니다. 일부 플랫폼은 생성 된 실행 파일에 "디버그"정보를 작성하며 실행중인 프로그램이 해당 정보를 검색 할 수있는 방법이있을 수 있지만 이러한 방법은 일반적으로 없습니다.

그러나 할 수있는 것은 매크로를 사용하여 구조를 정의하는 것입니다.

#define MAKE_ACME_STRUCT \ 
    FIELD(id,int,23) \ 
    X FIELD(name,char30,"Untitled") \ 
    X FIELD(info,int,19) \ 
    // LEAVE THIS COMMENT HERE 

을하고 구조체 문 중 하나를 확장 할 수 있도록 다음, 필드와 X 매크로 정의 된 다른 방법과 함께 MAKE_ACME_STRUCT 매크로 여러 번 호출, 또는에 대한 초기화 표현 : 예를 들어, 하나는 정의 할 수 있습니다 해당 구조체의 "기본"인스턴스 또는 구조체 필드를 설명하는 항목의 배열에 대한 초기화 표현식 [예 :

STRUCT_INFO acme_struct_info[] = { 
    {"id", STRUCT_INFO_TYPE_int, sizeof(ACME_STRUCT.id), offsetof(ACME_STRUCT.id)} 
    ,{"name", STRUCT_INFO_TYPE_char30, sizeof(ACME_STRUCT.name), offsetof(ACME_STRUCT.name)} 
    ,{"info", STRUCT_INFO_TYPE_int, sizeof(ACME_STRUCT.info), offsetof(ACME_STRUCT.info)} 
    ,{0}}; 

같은 구조체 내에서 사용되는 모든 종류의 단일 토큰 이름을 가질 필요 것, 그것은 그러한 각각의 이름에 대한 식별자 STRUCT_INFO_TYPE_nameGoesHere은 일부 런타임 라이브러리 유형을 식별하는 정의 할 수 그것을 이해하는 형태.

이러한 매크로는 거의 아름답지 않지만 정의하는 데 사용되는 모든 것이 동기화 상태로 유지된다는 장점이 있습니다. acme_struct 요소를 추가 또는 제거하면 해당 요소가 acme_struct_info에 저장된 구조체 멤버 목록에 추가되거나 제거됩니다.

관련 문제