컴파일 옵션에 따라 여러 기호를 정의 할 수도 있고 정의하지 않을 수도있는 여러 정적 라이브러리를 연결하는 프로그램이 있습니다. 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;
}
POSIX 환경에서'test'라는 이름의 프로그램은 문제의 큰 원인입니다.'test '라고도하는 표준 명령이 있습니다. 이것은 종종 현대 쉘에 내장되어 있습니다. –
사실! 그러나'PATH'에'.'이 있으면 얻을 수있는 자격이 있습니다. : P –