프로그래밍/리눅스 프로그래밍

[Linux] dynamic library (dlopen, dlsym, dlclose, dlerror) 사용법

jinkwon.kim 2021. 8. 11. 03:15
728x90
반응형

개요

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

값  설명
정상적으로 close됨
그 외의 값 dlerror로 에러 메시지 확인 필요
  •  

 

참고 사이트 

https://yaaam.tistory.com/entry/Linux-동적-라이브러리-로드-dlopen-dlsym-dlclose-dlerror 

https://wiki.kldp.org/wiki.php/DocbookSgml/C%2B%2B-dlopen

 

728x90
반응형