2010년 2월 18일 목요일

리눅스에서 동적라이브러리(DLL) 작성

동적라이브러리(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

 

참고 자료:

  1. 프로그램 라이브러리 하우투
  2. 리눅스 동적 라이브러리 분석
  3. Linux 애플리케이션을 위한 DLL 작성하기 (한글)

 

댓글 없음:

댓글 쓰기