2010-12-20 6 views
0

우선, this (< - 링크)을 보았습니다. 작동하지 않습니다.이 동적으로로드 된 라이브러리가로드하는 프로그램의 전역 변수에 액세스 할 수없는 이유는 무엇입니까?

$ gcc -shared -rdynamic -fpic -o liba.so a.c 
$ gcc -shared -fpic -o libb.so -L. -la b.c 
$ gcc -fpic -o a a.c 
$ ./a 
0x9262 

0x9263를 인쇄하지 않습니다

#include <stdio.h> 
#include <dlfcn.h> 

int global_var = 0x9262; 

int main(void) { 
    void *handle = dlopen("libb.so", RTLD_LAZY); 
    void (*func)(void); 
    char *err; 
    if (handle == NULL) { 
    fprintf(stderr, "%s\n", dlerror()); 
    return 1; 
    } 
    func = dlsym(handle, "func"); 
    if ((err = dlerror()) != NULL) { 
    fprintf(stderr, "%s\n", err); 
    return 2; 
    } 
    global_var = 0x9263; 
    func(); 
    return -dlclose(handle) * 3; 
} 

b.c :

#include <stdio.h> 

extern int global_var; 

void func(void) { 
    printf("0x%x\n", global_var); 
} 

컴파일 및 실행 나는 OS X의

A.C을 사용하고? 컴파일러 플래그의 많은 조합을 시도하고 그들 중 누구도 작동하지 않습니다.

답변

3

global_var의 두 인스턴스를 만들었습니다. 하나는 liba.so에 정의되어 있고 그 중 하나는 b.c이 참조하는 것입니다.

다른 하나는 a에 정의되어 있으며 그 중 하나가 사용자의 main() 기능이 참조하는 것입니다.

주 기능에서 liba.so의 변수를 참조하려면 정의 대신 extern 선언이 필요하며 해당 라이브러리 자체에 연결해야합니다.

+0

정확히 +1 (좀 더 자) – slezica

0

흥미로운 질문입니다. 답변도 흥미 롭습니다.

답장에서 언급했듯이 global_var의 정의는 두 가지로 작성되었습니다.

달성하려는 작업을 수행하려면 global_var이 기본 실행 파일에서 확인되어야합니다. 이를 위해 global_var을 메인 실행 파일에서 가져온 상태로 가져 오기 파일을 만들어야합니다. 가져 오기 파일에서 #!을 사용해야합니다. 이것 때문에.

그런 다음 라이브러리를 만드는 동안이 가져 오기 파일을 사용하십시오.

또한 메인 바이너리를 컴파일하는 동안 global_var 변수를 내 보내야합니다. 적절한 컴파일러 플래그를 사용하십시오.

내 유닉스 박스에서, 나는 이것을 시도하고 작동합니다.

# cat imp.imp 
#!. 

global_var 

cc main.c -bexpall 
cc lib.c -bM:SRE -bnoentry -bI:./imp.imp -bexpall -o libb.so 
+0

#이 게시물에 제대로 오지 않아 – cexpert

관련 문제