이 름
dlclose, dlerror, dlopen, dlsym − 동 적 링 크 로 더 에 대 한 프 로 그 래 밍 인 터 페 이 스 .
사 용 법
#include <dlfcn.h>
void *dlopen
(const char *filename, int
flag);
const char *dlerror(void);
void *dlsym(void *handle, char
*symbol);
int dlclose (void *handle);
특 수 기 호 : _init, _fini.
설 명
dlopen은 null로 끝 나 는 문 자 열 인 파 일 이 름 filename으 로 부 터 동 적 라 이 브 러 리 를 읽 어 온 다 . 동 적 라 이 브 러 리 를 위 해 정 해 지 지 않 은 "handle"을 리 턴 한 다 . 만 약 filename 이 상 대 경 로 ("/" 로 시 작 하 지 않 는 ) 라 면 , 다 음 위 치 에 서 화 일 을 찾 는 다 :
사 용 자 의 LD_LIBRARY_PATH 환 경 변 수 에 콜 론 (:)으 로 구 분 되 어 있 는 디 렉 토 리 리 스 트
/etc/ld.so.cache에 저 장 된 라 이 브 러 리 리 스 트
/lib가 뒤 따 르 는 , /usr/lib.
만 약 filename이 NULL 포 인 터 이 면 , 반 환 된 핸 들 은 메 인 프 로 그 램 에 해 당 하 는 것 이 다 .
라 이 브 러 리 에 있 는 외 부 참 조 는 이 라 이 브 러 리 의 의 존 관 계 목 록 에 있 는 라 이 브 러 리 와 전 에 RTLD_GLOBAL 플 래 그 로 열 린 다 른 라 이 브 러 리 를 사 용 하 는 것 으 로 해 결 된 다 . 만 약 실 행 파 일 이 "-rdynamic" 플 래 그 로 연 결 되 었 다 면 , 실 행 파 일 에 있 는 전 역 심 볼 은 동 적 으 로 탑 재 된 라 이 브 러 리 의 참 조 를 해 결 한 다 .
flag는 반 드 시 RTLD_LAZY - 동 적 라 이 브 러 리 의 코 드 가 실 행 되 어 정 의 되 지 않 은 심 볼 을 해 결 하 는 것 을 의 미 - 또 는 RTLD_NOW - dlopen 이 반 환 되 기 전 에 정 의 하 지 않 은 모 든 심 볼 을 해 결 하 는 것 을 의 미 - 이 어 야 만 한 다 . 그 리 고 이 과 정 이 수 행 되 지 않 으 면 실 패 할 것 이 다 . 추 가 적 으 로 , RTLD_GLOBAL은 라 이 브 러 리 안 에 정 의 된 외 부 심 볼 이 뒤 이 은 라 이 브 러 리 가 탑 재 되 는 것 이 가 능 하 게 할 경 우 에 flag와 OR 될 수 있 다 .
만 약 라 이 브 러 리 가 _init이 라 는 루 틴 에 전 달 될 경 우 , 라 이 브 러 리 에 있 는 코 드 는 dlopen이 반 환 되 기 전 에 수 행 될 것 이 다 . 만 약 같 은 이 름 의 라 이 브 러 리 가 dlopen()으 로 두 번 적 재 된 다 면 같 은 파 일 핸 들 을 리 턴 한 다 . dl 라 이 브 러 리 는 동 적 파 일 핸 들 의 링 크 수 를 관 리 한 다 . 그 래 서 동 적 라 이 브 러 리 가 dlopen에 의 해 성 공 적 으 로 호 출 된 만 큼 dlclose을 호 출 할 때 까 지 할 당 한 것 을 해 제 하 지 않 는 다 .
만 약 dlopen이 어 떤 이 유 에 서 라 도 실 패 를 한 다 면 NULL을 반 환 한 다 . dl 루 틴 (dlopen, dlsym, dlclose) 에 의 해 발 생 한 가 장 최 근 의 에 러 를 보 기 위 해 서 는 dlerror()을 호 출 해 야 한 다 . dlerror은 초 기 화 이 후 또 는 이 함 수 가 마 지 막 으 로 호 출 (연 속 적 으 로 이 함 수 가 두 번 호 출 되 면 두 번 째 호 출 의 반 환 값 은 항 상 NULL이 다 .) 된 후 아 무 런 에 러 가 발 생 하 지 않 았 다 면 NULL을 반 환 한 다 .
dlsym은 dlopen에 서 리 턴 된 동 적 라 이 브 러 리 의 핸 들 과 null로 끝 나 는 symbol 이 름 을 취 하 고 이 심 볼 의 적 재 된 주 소 를 반 환 한 다 . 만 약 심 볼 을 찾 지 못 하 면 , NULL을 반 환 한 다 ; 그 러 나 dlsym에 의 해 발 생 한 에 러 를 정 확 히 알 아 보 는 방 법 은 dlerror에 의 한 결 과 값 이 NULL이 아 닌 경 우 그 값 을 검 사 하 는 것 이 다 . 이 렇 게 하 는 이 유 는 심 볼 의 값 이 실 제 로 NULL이 되 는 경 우 가 있 기 때 문 이 다 . 그 리 고 dlerror이 다 시 호 출 될 때 에 는 NULL을 반 환 하 기 때 문 에 , 필 요 하 다 면 dlerror의 결 과 값 를 저 장 해 야 만 한 다 .
dlclose은 동 적 라 이 브 러 리 핸 들 인 handle에 대 한 참 조 계 수 를 하 나 감 소 시 킨 다 . 만 약 참 조 계 수 가 0이 되 고 다 른 어 떤 적 재 된 라 이 브 러 리 들 이 적 재 를 취 소 하 고 자 하 는 동 적 라 이 브 러 리 에 있 는 심 볼 을 사 용 하 지 않 으 면 , 동 적 라 이 브 러 리 는 적 재 가 취 소 된 다 . 만 약 동 적 라 이 브 러 리 가 _fini라 는 루 틴 에 전 달 될 경 우 , 라 이 브 러 리 의 적 재 가 취 소 되 기 바 로 전 에 이 루 틴 이 호 출 될 것 이 다 .
예 제
math 라 이 브 러 리 를 적 재 하 고 , 코 사 인 2.0을 출 력 한 다 :
#include <dlfcn.h>
int main(int
argc, char **argv) {
void *handle = dlopen ("/lib/libm.so", RTLD_LAZY);
double (*cosine)(double) = dlsym(handle, "cos");
printf ("%f\n", (*cosine)(2.0));
dlclose(handle);
}
만 약 프 로 그 램 이 름 이 "foo.c"라 면 다 음 과 같 은 명 령 어 로 프 로 그 램 을 컴 파 일 할 수 있 다 :
gcc -rdynamic -o foo foo.c -ldl
같 은 방 법 으 로 하 자 . 그 러 나 매 단 계 마 다 에 러 체 크 를 하 자 :
#include <stdio.h>
#include <dlfcn.h>
int main(int
argc, char **argv) {
void *handle;
double (*cosine)(double);
char *error;
handle = dlopen
("/lib/libm.so", RTLD_LAZY);
if (!handle) {
fputs (dlerror(), stderr);
exit(1);
}
cosine =
dlsym(handle, "cos");
if ((error = dlerror()) != NULL) {
fprintf (stderr, "%s0, error);
exit(1);
}
printf
("%f\n", (*cosine)(2.0));
dlclose(handle);
}
감 사
dlopen 인 터 페 이 스 표 준 은 솔 라 리 스 에 서 부 터 시 작 되 었 다 . 리 눅 스 의 dlopen에 대 한 구 현 은 Mitch D’Souza, David Engel, Hongjiu Lu, Andreas Schwab와 그 외 다 수 의 도 움 을 받 아 Eric Youngdale이 하 였 다 . 이 매 뉴 얼 페 이 지 는 Adam Richter가 작 성 하 였 다 .
관 련 항 목
ld(1), ld.so(8), ldconfig(8), ldd(1), ld.so.info.
역 자
정 동 현 <dhjung [AT] serome.kr>, 2000년 4월 22일