[Linux] 동적 및 정적 라이브러리

머리말

콘텐츠

1. 라이브러리가 있는 이유 2. 정적
라이브러리 2.1 .c
    파일을 동일한 이름 의 .o 파일로
    생성
    

    
    
    

  • 정적 라이브러리(.a): 프로그램이 컴파일 및 링크될 때 프로그램이 라이브러리의 바이너리 코드를 내 프로그램의 실행 파일에 복사하고 프로그램 실행 시 정적 라이브러리가 더 이상 필요하지 않습니다.

  • 동적 라이브러리(.so): 동적 라이브러리의 코드는 프로그램이 실행 중일 때만 링크되며, 라이브러리의 코드는 여러 프로그램에서 공유됩니다.

C 언어 라이브러리와 같은:

  • 동적 라이브러리 libc.so
  • 정적 라이브러리 libc.a

라이브러리의 명명 규칙은 lib 헤더 + 라이브러리 이름 + 접미사 lib 접두사를 제거하고 . 접미사를 제거하고 나머지는 라이브러리 이름입니다.

실행 가능한 프로그램을 생성하는 방법에는 동적 연결과 정적 연결의 두 가지가 있습니다.

ldd filename # 查看链接方式

여기에 이미지 설명 삽입
여기에 이미지 설명 삽입

1. 도서관이 있는 이유

개발할 때 다른 사람의 소스 코드 컴파일, 다른 사람이 제공한 타사 라이브러리 호출, 다른 사람이 제공한 네트워크 기능 인터페이스 호출 등을 포함하여 다른 사람이 작성한 코드를 자주 사용합니다.

여기에 이미지 설명 삽입

왜 다른 사람의 코드를 사용해야 합니까?

  • 개발 효율성 향상
  • 프로그램 견고성 향상

이른바 강건함이란 프로그램의 강건함을 말하며, 각 모듈 간의 결합도가 낮다. 타사 라이브러리의 경우 문제가 없다고 생각합니다. 내 프로그램에 오류가 있다면 호출된 라이브러리 자체에 문제가 있다고 의심할 필요는 없지만 내가 작성한 코드 논리에는 문제가 있어야 하므로 오류 범위가 다음과 같이 줄어듭니다. 확인했습니다. 물론 여기에 있는 라이브러리는 STL과 같은 표준 라이브러리와 같은 일부 권위 있는 라이브러리를 참조해야 합니다.

음, 다른 사람의 코드를 어떻게 사용하는지, 라이브러리를 패키징하고 사용하는 방법을 배우는 것이 매우 중요합니다.

2. 정적 라이브러리

이 실험을 위해 5개의 원본 파일이 있습니다.

add.h
add.c
sub.h
sub.c
main.c

#pragma once
#include <stdio.h>
int add(int x, int y);
#include "add.h"
int add(int x, int y) {
    
    
  return x+y;
}
#pragma once
#include <stdio.h>
int sub(int x, int y);
#include "sub.h"
int sub(int x, int y) {
    
    
  return x-y;
}
#include <stdio.h>
#include "add.h"
#include "sub.h"
int main() {
    
    
  printf("%d\n%d\n", add(20, 10), sub(20, 10));
  return 0;
}

2.1 .c 파일을 같은 이름의 .o 파일로 생성

정적 라이브러리를 호출한다는 것은 프로그램이 링크될 때 정적 라이브러리의 바이너리 코드를 실행 파일에 링크하는 것을 의미하므로 실행 시 정적 라이브러리를 찾을 필요가 없습니다.

글쎄, 정적 라이브러리는 연결 단계에서 실행 파일에 연결되므로

전처리 - 컴파일 - 어셈블 - 링크

어셈블리 단계를 완료해야 합니다 어셈블리는 어셈블리 코드를 기계어로 변환하는 것이고 생성된 파일은 .o파일 입니다

gcc -c add.c 
gcc -c sub.c

여기에 이미지 설명 삽입

2.2 정적 라이브러리 만들기

정적 라이브러리를 만드는 핵심은 여러 .o 파일을 패키징하는 것입니다.

ar -ac libmymath.a add.o sub.o

여기에 이미지 설명 삽입

ar -tv를 사용하여 정적 라이브러리에 포함된 파일을 봅니다.
여기에 이미지 설명 삽입

2.3 정적 라이브러리 사용

slib 폴더에 세 개의 파일 add.o sub.o libmymath.a를 넣습니다.

1. -Imain.c를 컴파일하고 링크할 때 헤더 파일 디렉토리를 가져와야 합니다.

gcc main.c -o main -I ./slib/

여기에 이미지 설명 삽입
뭔가 빠진 것 같다

2. -L라이브러리 파일이 있는 디렉토리를 가져오기 위해 사용

gcc main.c -o main -I ./slib/ -L ./slib/

여기에 이미지 설명 삽입
뭔가 빠진 것 같다

3. -l라이브러리의 이름을 사용하십시오(lib와 . 접미사 사이의 부분).

gcc main.c -o main -I ./slib/ -L ./slib/ -lmymath

이 시점에서 실행 파일이 성공적으로 생성됩니다.

여기에 이미지 설명 삽입
운영:
여기에 이미지 설명 삽입

3. 동적 라이브러리

  • 동적 라이브러리와 연결된 실행 파일에는 외부 함수가 있는 개체 파일의 전체 기계 코드가 아니라 사용하는 함수 항목 주소의 테이블만 포함됩니다.

  • 실행 파일이 실행되기 시작하기 전에 외부 기능의 기계어 코드는 운영 체제에 의해 디스크의 동적 라이브러리에서 메모리로 복사되며, 이 프로세스를 동적 연결이라고 합니다.

  • 동적 라이브러리는 여러 프로그램에서 공유할 수 있으므로 동적 연결은 실행 파일을 더 작게 만들고 디스크 공간을 절약합니다. 운영 체제는 가상 메모리 메커니즘을 사용하여 물리적 메모리의 동적 라이브러리를 라이브러리를 사용하는 모든 프로세스에서 공유할 수 있도록 하여 메모리와 디스크 공간을 절약합니다.

3.1 동적 라이브러리 만들기

1. 위치 독립 코드 생성

이 동적 라이브러리 자체는 공유 영역에 매핑된 메모리의 어떤 영역에도 로드되지 않으며 모든 위치는 라이브러리의 코드 주소의 상대적인 변경에 영향을 미치므로 라이브러리의 실행 불가능한 라이브러리 코드가 매핑되는 결과를 초래합니다. 공유 영역, 각 프로세스가 사용 동일한 코드, 메모리 낭비 없음

gcc -fPIC -c add.c sub.c

여기에 이미지 설명 삽입


2. 동적 라이브러리 파일 생성

gcc -shared -o libmymath.so add.o sub.o 

여기에 이미지 설명 삽입


3.2 동적 라이브러리를 사용하여 실행 파일 생성

gcc main.c -o main -I dlib/ -L dlib/ -lmymath

여기에 이미지 설명 삽입


3.3 달리기

여기에 이미지 설명 삽입
실행 main에서 오류가 발견되었습니다. 무슨 일이 일어났습니까?

우리가 거기 있을 때 이미 编译헤더 파일 디렉토리, 라이브러리 파일 디렉토리, 라이브러리 파일 이름을 지정하지 않았습니까?

아 컴파일할 때 지정했는데 지금은 실행단계인데 실행단계에서는 라이브러리 파일을 어디다 찾는지 지정이 안되는데 당연히 못찾겠네요.

3가지 해결 방법:

  • libmymath.so일반적으로 시스템 공유 라이브러리 경로에 사본을 복사 /usr/lib64하거나/usr/lib

여기에 이미지 설명 삽입

  • LD_LIBRARY_PATH 환경 변수에 dlib 디렉토리 추가

다음은 환경 변수입니다. LD_LIBRARY_PATH시스템이 기본적으로 동적 라이브러리 파일을 찾는 디렉토리를 저장합니다
여기에 이미지 설명 삽입
. 환경 변수 내보내기:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/root/class101/linux/lesson18/dlib
  • ldconfig 구성/etc/ld.so.conf.d

/etc/ld.so.conf.d 디렉토리에 임의로 .conf 파일을 생성하고 .conf 파일에 동적 라이브러리 디렉토리를 작성한다.

echo "/root/class101/linux/lesson18/dlib" > /etc/ld.so.conf.d/test.conf
ldconfig

여기에 이미지 설명 삽입

4. 몇 가지 세부 사항

세부 사항 하나

C 언어가 컴파일할 때 -I -L -l과 같은 옵션을 명시적으로 사용하지 않는 이유
1. 헤더 파일과 라이브러리 파일은 기본 경로에서 gcc에 의해 발견됩니다 . 2. gcc
가 C 코드를 컴파일할 때 기본적으로 libc를 찾아야 합니다.

이러한 옵션도 사용하지 않으려면 어떻게 해야 합니까?
헤더 파일 라이브러리 파일을 기본 경로로 복사 -> 라이브러리 설치

세부 사항 2

gcc 기본 동적 링크, 동적 링크가 없으면 정적 링크로 이동

메이크파일

main: main.c    
  gcc -o $@ $^ -I ./dlib -L ./dlib -lmymath    
.PHONY: clean    
clean:    
  rm -f main 

추천

출처blog.csdn.net/m0_52640673/article/details/123275558