ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Linux] Dynamic Loading
    공부/Embedded 2025. 1. 27. 02:21

    동적 라이브러리 사용 이유

    - 정적 라이브러리는 컴파일 타임에 실행 바이너리에 포함되어야 하지만, 동적 라이브러리는 실행 파일에 포함되지 않아도 된다.

    - 따라서 동적 라이브러리는 앱의 컴파일과 별개로 동작할 수 있고, 앱의 실행 파일에 포함되지 않기 때문에 앱의 초기 실행시에 메모리에 로드될 필요가 없다.

    - 따라서 앱 실행 속도나 메모리 사용량을 줄일 수 있다.

     

    동적 라이브러리 로드

    - shared library라는 형식으로 라이브러리를 제작

    - 실행 시점에 사용할 라이브러리를 연결하여 사용

    - 라이브러리의 확장자는 . so(shared object), 동적 라이브러리

    - 대상 프로그램 컴파일 시 -ldl 옵션를 줘서 컴파일

     

    dlfcn.h

    #include <dlfcn.h>로 사용

     

    void *dlopen(const char *filename, int flag)

    filename: 파일명, 로드할 동적 라이브러리 .so 파일

    flag: .so 파일을 메모리로 적재하는 방법이나 적재 시점

      - RTLD_LAZY: so에 포함된 함수가 최초 호출되는 시점에 해당 so파일을 로드

      - RTLD_NOW: dlopen() 호출과 동시에 로드

        * | 옵션으로 필요한 flag들을 설정, A | B | ..., RTKD_GLOBAL, RTLD_LOCAL, RTLD_NODELETE, RTLD_NOLOAD, RTLD_DEEPBIND

    반환값: NULL(실패 시), shared object에 대한 핸들을 반환(성공 시)

     

     

    void *dlsym(void *handle, const char *symbol)

    handle: shared object에 대한 핸들

    symbol: shared object에서 찾고자하는 함수명이나 변수명

    반환값: NULL(실패 시), 해당 symbol에 대한 주소 값, 변수 또는 함수 포인터 형태로 반환(성공 시)

     

    int dlclose(void *handle)

    handle: shared object에 대한 핸들

    반환값: 0(성공 시), 그 외(실패 시)

     

    char* dlerror(void)

    반환 값: 에러에 대한 문자열 반환, 없다면 NULL 반환

     

    #include <dlfcn.h>
    
    int main(){
        ~~~
        // 1
        void* handle = dlopen("./lib.so", RTLD_LAZY);
        // 2
        void (*func)() = (void (*)())dlsym(handle, "func_1");
        // 3
        dlclose(handle);
        ~~~
        return 0;
    }

     

     

     

     

    코드

     

    CMakeLists.txt

    cmake_minimum_required(VERSION 3.10)
    
    project(dynamic_loading)
    
    add_library(hello SHARED hello.c)
    
    add_executable(main main.c)
    
    target_link_libraries(main PRIVATE dl)

     

    hello.c

    #include <stdio.h>
    
    void print_hello_world(){
    	printf("Hello World !!!\n");
    }

     

    main.c

    #include <dlfcn.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
    	void *handle;
    	void (*print_hello_world)();
    
    	handle = dlopen("./libhello.so", RTLD_LAZY);
    	if(!handle){
    		fprintf(stderr, "dlopen error: %s\n", dlerror());
    		exit(1);
    	}
    
    	*(void **)(&print_hello_world) = dlsym(handle, "print_hello_world");
    	if(!print_hello_world){
    		fprintf(stderr, "dlsym error: %s\n", dlerror());
    		dlclose(handle);
    		exit(1);
    	}
    
    	print_hello_world();
    	dlclose(handle);
    	return 0;
    }

     

    실행결과

    '공부 > Embedded' 카테고리의 다른 글

    [Zephyr] Workqueue  (0) 2025.01.07
    [Zephyr] System Thread  (0) 2025.01.07
    [Zephyr] Thread  (0) 2025.01.06
    AMBA Bus Protocol  (3) 2024.12.08
    [Renode] .repl(Platform description format)  (1) 2024.12.01
Designed by Tistory.