Linux에서 동적 링크 라이브러리 컴파일 및 사용 설명

8580 단어

linux 라이브러리 소개


두 가지 라이브러리
  • 정적 라이브러리
  • 동적 라이브러리의 차이점은 코드가 불러오는 시간이 다르기 때문이다.정적 라이브러리의 코드는 컴파일 과정에서 실행 가능한 프로그램에 불러왔기 때문에 부피가 비교적 크다.공유 라이브러리의 코드는 실행 가능한 프로그램이 실행될 때만 메모리를 불러옵니다. 컴파일 과정에서 간단한 인용만 있기 때문에 코드 부피가 비교적 작습니다
  • 라이브러리의 저장 위치 및 명명 사양
    저장: 일반적으로/usr/lib 및/lib 아래에 명명된 사양: 1.정적 라이브러리의 이름은 일반적으로libxxx입니다.a, 여기서 xxx는 이lib의 이름입니다.동적 라이브러리의 이름은 일반적으로libxxx입니다.so.major.minor, xxxx는 이 동적 라이브러리의 이름이고, major는 메인 버전 번호이며, minor는 부 버전 번호이다.
    실행 가능한 프로그램이 어떤 라이브러리에 의존하는지 보기 ldd 명령은 실행 가능한 프로그램이 의존하는 공유 라이브러리를 볼 수 있습니다
    새로 라이브러리를 설치한 후에 어떻게 시스템에서 그를 찾을 수 있습니까?/lib 또는/usr/lib에 설치되어 있으면,ld는 기본적으로 찾을 수 있으며, 다른 조작이 필요 없습니다.다른 디렉토리에 설치하려면/etc/ld에 추가해야 합니다.so.cache 파일의 단계는 다음과 같습니다./etc/ld 편집so.conf 파일, 라이브러리 파일이 있는 디렉터리에 가입하는 경로 2.ldconfig를 실행하면/etc/ld를 다시 만듭니다.so.cache 파일

    동적 링크 라이브러리 작성


    헤더 파일 so.h
    #ifndef  SO_H
    #define  SO_H
    
    int add(int a, int b);
    
    
    #endif  /*SO_H*/

    실행 파일 so.c
    #include "so.h"
    
    int add(int a, int b)
    {
        return a + b;
    }

    동적 링크 라이브러리 컴파일

    gcc -fPIC -c so.c//생성so.o gcc -shared -o libtest.so so.o(위의 두 줄을 한 줄로 통합할 수 있음: gcc so.c -fPIC -shared -o libtest.so) 참고:
  • -fpic는 출력의 대상 모듈을 재배치 가능한 주소 방식에 따라 생성한다(즉 위치와 무관하다).
  • -shared는 대응하는 원본 파일을 대응하는 동적 링크 라이브러리 파일libtest로 생성하도록 지정합니다.so 파일은 nm-g libtest를 통과합니다.so에서 알 수 있듯이 기호표에 이미dd라는 기호가 있습니다:
  • $ nm -g libtest.so 
    0000000000000670 T add
    0000000000201030 B __bss_start
                     w __cxa_finalize@@GLIBC_2.2.5
    0000000000201030 D _edata
    0000000000201038 B _end
    0000000000000684 T _fini
                     w __gmon_start__
    0000000000000540 T _init
                     w _ITM_deregisterTMCloneTable
                     w _ITM_registerTMCloneTable
                     w _Jv_RegisterClasses

    동적 라이브러리 사용

  • 스텔스 링크(컴파일할 때 링크) 메인main.c:
  • #include 
    #include "so.h"
    
    int main(int argc, char *argv[])
    {
        printf("%d
    "
    , add(1, 2)); return 0; }
    gcc main.c -L. -ltest -o test를 사용하여 컴파일합니다.
  • - L: 라이브러리 파일의 검색 경로 추가
  • -l: 링크가 필요한 라이브러리를 지정합니다.이 이름은 머리lib과 접미사에 있습니다.so의 이름, 예를 들어 위 동적 라이브러리libtest.so의 l 매개 변수는 -l 테스트
  • 입니다.
    이 때 readelf test -d 실행 가능한 파일test를 생성한 다이나믹 섹션에서libtest에 의존하는 것을 볼 수 있습니다.쏘다
    $ readelf test -d
    
    Dynamic section at offset 0xe18 contains 25 entries:
      Tag        Type                         Name/Value
     0x0000000000000001 (NEEDED)             Shared library: [libtest.so]
     0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
    ......

    dynamic symbols에도 undefined symbol (add)
    $ nm -D test 
                     U add
    0000000000601048 B __bss_start
    0000000000601048 D _edata
    0000000000601050 B _end
    00000000004007b4 T _fini
                     w __gmon_start__
    0000000000400578 T _init
                     w _ITM_deregisterTMCloneTable
                     w _ITM_registerTMCloneTable
                     w _Jv_RegisterClasses
                     U __libc_start_main
                     U printf

    스텔스 링크를 실행하기 전에 환경 변수를 설정하거나 앞에 생성된libtest를 주의해야 합니다.so 시스템 경로로 복사합니다. 그렇지 않으면 동적 라이브러리를 찾을 수 없습니다.
    $ ./test 
    ./test: error while loading shared libraries: libtest.so: cannot open shared object file: No such file or directory
    
    $ export LD_LIBRARY_PATH=.
    
    $ ./test 
    3
  • 명시적 링크(런타임 링크) 작성 마스터dynmain.c
  • #include 
    #include 
    
    int main(int argc, char *argv[])
    {
        void *dl = NULL;
        int (*add)(int a, int b);
        dl = dlopen( "./libtest.so", RTLD_LAZY);
        if( dl == NULL )
        {
            printf("so loading error.
    "
    ); return 1; } add = (int(*)(int, int))dlsym(dl, "add"); if( dlerror() != NULL ) { printf("fun load error.
    "
    ); return 1; } printf("%d
    "
    , add(1, 2)); return 0; }
    LD_LIBRARY_PATH를 사용하여 컴파일합니다.
    이때 gcc dyn_main.c -ldl -o dyn_test를 통해 알 수 있듯이dyn테스트는libtest에 의존하지 않습니다.so:
    $ readelf dyn_test -d
    
    Dynamic section at offset 0xe18 contains 25 entries:
      Tag        Type                         Name/Value
     0x0000000000000001 (NEEDED)             Shared library: [libdl.so.2]
     0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
    ......

    dyn_테스트의 dynamic symbols에도 add가 없습니다.
    $ nm -D dyn_test 
                     U dlerror
                     U dlopen
                     U dlsym
                     w __gmon_start__
                     w _ITM_deregisterTMCloneTable
                     w _ITM_registerTMCloneTable
                     w _Jv_RegisterClasses
                     U __libc_start_main
                     U printf
                     U puts

    실행 프로그램도 환경 변수를 설정할 필요가 없습니다 readelf dyn_test -d
    $ ./dyn_test 
    3

    참고 자료 Linux에서 링크 동적 라이브러리 컴파일

    좋은 웹페이지 즐겨찾기