개요
dlopen의 경우 library를 run time에 Load하여 사용 하려고 할 때 사용 합니다.
헤더
#include <dlfnc.h>
dlopen 관련 함수
#include <dlfcn.h>
#라이브러리를 open 합니다.
void *dlopen (const char *filename, int flag);
#라이브러리 오픈 관련 에러는 표현 합니다.
const char *dlerror(void);
#so파일의 symbol 정보를 가져옵니다.
#반환
# - 해당 symbol과 연관된 주소값이 반환
#사용법
# - 이를 받아서 함수포인터 또는 변수로 저장
void *dlsym(void *handle, const char *symbol);
#라이브러리를 close 합니다.
int dlclose (void *handle);
출처: https://www.it-note.kr/186 [IT 개발자 Note:티스토리]
Sample Code
1) dynamic library code
- 함수 선언시 extern "C"로서 선언 해야 합니다.그래야 C처럼 함수의 이름을 symbol의 이름으로 사용합니다.
extern "C" 상세 설명
C++에는 extern "C"라는, C binding으로 함수를 정의하는 특별한 키워드가 있습니다. extern "C"로서 선언된 함수는 C처럼 함수의 이름을 symbol의 이름으로 사용합니다. 이러한 이유로, 멤버함수가 아닌 함수들만이 extern "C"로서 선언될 수 있고, 이러한 함수들은 오버로딩을 할 수 없습니다.
이런 심한 제한이 있지만, extern "C"함수는 C 함수처럼 dlopen을 써서 동적으로 적재할 수 있기 때문에 매우 유용합니다.
이것은 extern "C"로 선언된 함수가 C++ 코드를 포함할 수 없다는 것을 의미하는 것이아닙니다. 이런 함수는 어느 종류의 인자라도 받을 수 있고, C++의 특징을 쓸 수 있습니다.
- test_func.hpp
extern "C" int test_dl_func();
- test_func.cpp
#include <iostream>
#include "test_func.hpp"
int test_dl_func()
{
std::cout << "call test_dl_func" << std::endl;
return 0;
}
2) dynamic library 사용하는 main 함수
#include <iostream>
#include <dlfcn.h>
#include "./test_func.hpp"
int main(int argc, char** argv)
{
void *handle = dlopen("./libtest_func.so", RTLD_NOW);
char *error = nullptr;
if (handle) {
typedef int (*test_dl_func_t)();
test_dl_func_t test_dl_func = (test_dl_func_t)dlsym(handle, "test_dl_func");
if((error = dlerror()) != NULL) {
printf("dlsym error: %s\n", error);
dlclose(handle);
return -1;
}
test_dl_func();
dlclose(handle);
} else {
if((error = dlerror()) != NULL) {
printf("dlopen error: %s\n", error);
return -1;
}
}
}
3) Compile을 위한 CMakeLists.txt
- 관련 설명 : [cmake] cmake 기초 부터 활용 까지
#cmake 최소 버전
cmake_minimum_required(VERSION 3.18.1)
#프로젝트 이름
project(dltest)
#CMake 옵션 처리
set(CMAKE_VERBOSE_MAKEFILE ON)
#컴파일 옵션 추가
add_compile_options(-std=c++11 -ggdb3 -O3 -Wall -fPIC)
#define 추가
add_definitions(-D_REENTRANT)
#header include 경로
include_directories("./")
#라이브러리 링크 디렉토리 경로
link_directories()
#cmake 변수 처리
file(GLOB main_src "./dl_main.cpp")
#실행 파일 생성
add_executable(${PROJECT_NAME} ${main_src})
#dynamic library생성
add_library(test_func SHARED test_func.cpp)
#특정 실행 파일에 적용될 라이브러리 링크추가
target_link_libraries(${PROJECT_NAME}
-Wl,--no-as-needed
-Wl,--rpath,./
dl
pthread
)
함수별 상세 용도
1) void *dlopen(const char *filename, int flag);
- dynamic library을 open 합니다.
(1) 매개 변수
매개 변수 명 | 필수 여부 | 값 | 설명 |
filename | 필수 | "libtest.so" | 로드할 동적 라이브러리 파일명 |
flag | 필수 | [ RTLD_LAZY | RTLD_NOW ] |
RTLD_LAZY - shared object에 포함된 함수가 최초 호출되는 시점에 해당 so 파일이 로딩됨. shared object에 포함된 전역변수는 호출과 동시에 생성. RTLD_NOW - dlopen()함수 호출과 동시에 loading |
옵션 | RTLD_GLOBAL | loading한 이 라이브러리를 다른 프로그램에서도 사용 | |
RTLD_LOCAL | loading한 이 라이브러리는 이 프로그램에 한해서 사용 (default) | ||
RTLD_NODELETE | dlclose()시에도 메모리에서 내리지 않는다. | ||
RTLD_NOLOAD | dlopen()해서 메모리에 로딩하지 않는다. (라이브러리의 존재 여부 및 오류 체크용) |
(2) return
값 | 설명 |
void* | void* 형태의, shared object에 대한 handle 반환 |
NULL | 로딩 실패 |
2) char *dlerror(void)
- dynamic library을 open 시 발생한 에러를 표기 합니다.
(1) 매개 변수
- 엇음
(2) return
값 | 설명 |
문자열 | 에러가 방생하면 반환됨 |
NULL | 만약 에러가 발생한 적이 없을 경우 |
3) void *dlsym(void *handle, const char *symbol)
- dynamic library의 존재한 함수를 매핑 합니다.
(1) 매개 변수
매개 변수 명 | 값 | 설명 |
handle | handle pointer | dlopen에서 반환받은 shared object handle |
symbol | "test_function" | shared object에서 찾고자 하는 함수명 또는 변수명 |
(2) return
값 | 설명 |
NULL이 아님 | 해당 symbol과 연관된 주소값이 반환 |
NULL | - symbol이 존재하지 않음 - 에러의 경우 dlerror 함수를 호출하면 에러의 원인 파악 가능 |
4) int dlclose(void *handle)
- dynamic library을 close 합니다.
(1) 매개 변수
매개 변수 명 | 값 | 설명 |
handle | handle pointer | dlopen에서 반환받은 shared object handle |
(2) return
값 | 설명 |
0 | 정상적으로 close됨 |
그 외의 값 | dlerror로 에러 메시지 확인 필요 |
참고 사이트
https://yaaam.tistory.com/entry/Linux-동적-라이브러리-로드-dlopen-dlsym-dlclose-dlerror
https://wiki.kldp.org/wiki.php/DocbookSgml/C%2B%2B-dlopen
'프로그래밍 > 리눅스 프로그래밍' 카테고리의 다른 글
bash shell 키워드 의미 (0) | 2021.08.30 |
---|---|
[Linux] realpath 구하기 (0) | 2021.08.11 |
[cmake] cmake 기초 부터 활용 까지 (0) | 2021.06.17 |
[bash] 알면 좋은 팁!! (0) | 2021.06.07 |
[bash script] 유용한 bash 스크립트 모음 (0) | 2021.06.07 |