동적라이브러리(DLL)은 시스템 자원(디스크 및 메모리 공간)을 절약하고, 프로그램의 유지보수를 쉽게하는 장점이 있다.
여기서는 특정 어플리케이션을 위한 동적라이브러리 작성 및 사용방법에 대해 알아본다.
라이브러리 API 함수는
- "dlopen" : 메모리에 라이브러리를 맵핑하고 핸들을 리턴
- "dlsym" : 함수 포인터를 리턴
- "dlerror" : 오류 문자열 포인터를 리턴, NULL은 정상
- "dlclose" : 핸들을 닫고 맵핑을 해제
동적라이브러리는 "dlopen"에서 절대경로를 설정해서 라이브러리를 지정할 수 있다. 절대 경로가 지정되지 않으면,
- "LD_LIBRARY_PATH" 환경 변수에서 지정된 경로
- "/etc/ld.so.cache"의 라이브러리 리스트
- "/usr/lib"와 "/lib" 경로
에서 라이브러리를 찾게 된다. Shell에서 현재 디렉토리를 "LD_LIBRARY_PATH"에 설정하는 것은
export LD_LIBRARY_PATH=`pwd`
이고, pwd를 인용하는 "`"는 TAB 위에 있는 [~/`]키를 사용해야 한다.
다음의 libhello.c, testdll.c, test_dll.sh 파일로 동적라이브러리 예제를 작성하고 동작을 확인할 수 있다.
libhello.c
#include "stdio.h" #include "string.h" int hello(char *msg) { printf("%s\n", msg); return strlen(msg); }
testdll.c
#include "stdio.h" #include "string.h" #include "unistd.h" #include "dlfcn.h" #define _MAX_STRING 80 #define _LIB_FILE "libhello.so" int invoke_method(char *lib, char *method, char *argument) { void *dl_handle; int (*func)(char *); char *error; int ret = 0; /* 공유 목적 파일을 연다. */ dl_handle = dlopen(lib, RTLD_LAZY); if (!dl_handle) { printf("!!! %s\n", dlerror()); return -1; } /* 목적 파일에서 심볼(메서드)을 찾는다. */ func = dlsym(dl_handle, method); error = dlerror(); if (error != NULL) { printf("!!! %s\n", error); return -2; } /* 찾아낸 메서드를 호출한다. */ ret = (*func)(argument); /* 객체를 닫는다. */ dlclose(dl_handle); return ret; } int main(int argc, char *argv[]) { char lib[_MAX_STRING+1]; char method[] = "hello"; char argument[] = "Hello, library world..."; char pwd[_MAX_STRING+1]; getcwd((char *)pwd, _MAX_STRING); sprintf(lib, "%s/%s", pwd, _LIB_FILE); printf("Result: %d\n", invoke_method(lib, method, argument)); }
test_dll.sh
# Build library if [ -f libhello.o ]; then rm libhello.o fi gcc -c -fPIC libhello.c if [ -f libhello.so ]; then rm libhello.so fi gcc -shared -lc -o libhello.so libhello.o # Build test program if [ -f testdll.o ]; then rm testdll.o fi gcc -o testdll testdll.c -ldl # Run test program ./testdll
참고 자료:
댓글 없음:
댓글 쓰기