2014-12-17 20 views
4

컴파일 옵션에 따라 여러 기호를 정의 할 수도 있고 정의하지 않을 수도있는 여러 정적 라이브러리를 연결하는 프로그램이 있습니다. OS X에서는 기호 주소를 얻기 위해 NULL 핸들과 함께 dlsym(3)을 사용합니다. 그러나 Linux에서는 dlsym(3)이 항상 NULL을 반환합니다.정적으로 링크 된 라이브러리에서 변수를 찾기 위해 dlsym() 사용

함수와 변수를 포함하는 정적 라이브러리에서 링크하고 그 주소를 인쇄하려고하는 간단한 프로그램 (아래 소스)을 고려하십시오. 우리는 프로그램이 문자가 포함되어 있는지 확인 할 수 없다 : 그러나

$ nm -C test | grep "test\(func\|var\)" 
0000000000400715 T testFunc 
0000000000601050 B testVar 

, 프로그램이 실행될 때, 어느 쪽도 찾을 수 있습니다 :

$ ./test 
testVar: (nil) 
testFunc: (nil) 

우리가 리눅스에서 가능 무엇을하려고하고, glibc는의의를 사용하여 dlsym(3)의 구현?

메이크

LDFLAGS=-L. 
LDLIBS=-Wl,--whole-archive -ltest -Wl,--no-whole-archive -ldl 

libtest.o: libtest.c libtest.h 
    libtest.a: libtest.o 
test: test.o libtest.a 
clean: 
    -rm -f test test.o libtest.o libtest.a 

#include "libtest.h" 
void *testVar; 
int testFunc(int x) { return x + 42; } 

TEST.C

,536,913 libtest.c
#pragma once 
extern void *testVar; 
extern int testFunc(int); 

libtest.h

(공백 미안) 63,210

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

int main(int argc, char *argv[]) { 
    void *handle = dlopen(NULL, 0); 
    void *symbol = dlsym(handle, "testVar"); 
    printf("testVar: %p\n", symbol); 
    symbol = dlsym(handle, "testFunc"); 
    printf("testFunc: %p\n", symbol); 
    return 0; 
} 
+5

POSIX 환경에서'test'라는 이름의 프로그램은 문제의 큰 원인입니다.'test '라고도하는 표준 명령이 있습니다. 이것은 종종 현대 쉘에 내장되어 있습니다. –

+2

사실! 그러나'PATH'에'.'이 있으면 얻을 수있는 자격이 있습니다. : P –

답변

4

당신은 너무

LDFLAGS += -rdynamic -L. 

그런 다음 모든 심볼이 동적 심볼 테이블에서 하나 BTW는 dlsym

사용하는 (ld(1) 또는 --export-dynamic) -rdynamic와 프로그램을 연결해야 visibility attribute이 관심의 대상이 될 수 있습니다.

+2

나 같은, 누가 알지 못했는지 (매뉴얼에서) : _'-rdynamic' :'-export-dynamic' 플래그를 지원하는 타겟에서 ELF 링커에게 넘겨 줘라. 링커는 사용 된 기호뿐만 아니라 모든 기호를 동적 기호 테이블에 추가하도록 지시합니다. 이 옵션은'dlopen'을 사용하거나 프로그램 내에서 역 추적을 얻을 때 필요합니다. – legends2k