유 닉 스/Linux 환경 에서 정적/동적 라 이브 러 리 를 만 들 고 사용 합 니 다.
대체적으로 라 이브 러 리 의 존 재 는 두 가지 이유 가 있 는데 하 나 는 코드 의 재 활용 이 고 다른 하 나 는 성명 과 실현 의 분리 이다.기능 이 비슷 한 사용 모듈 을 라 이브 러 리 로 밀봉 하여 코드 의 재 활용,관리 와 배 포 를 매우 간단 하 게 만 들 었 습 니 다.예 를 들 어 유명한 오픈 소스 그래 픽 라 이브 러 리 ncurses 는 스스로 컴 파일 할 수 있 고 이미 컴 파일 된 라 이브 러 리 파일 을 직접 사용 할 수 있 습 니 다.또한 라 이브 러 리 는 바 이 너 리 파일 이기 때문에 특정한 의미 에서 기능 의 실현 부분 을 숨 기 면 상업 코드 의 보호 에 방식 을 제공 합 니 다.라 이브 러 리 파일 은 링크 방식 과 시기 에 따라 동적 라 이브 러 리 와 정적 라 이브 러 리 로 나 눌 수 있 습 니 다.다음은 리 눅 스 환경 에서 의 생 성과 사용 방법 을 소개 합 니 다.
정적 연결 라 이브 러 리
정적 라 이브 러 리 는 프로그램의 링크 단계 에서 사용 되 는 코드 가 실행 가능 한 파일 의 라 이브 러 리 로 직접 연 결 됩 니 다.정적 링크 의 실행 가능 한 프로그램 은 필요 한 모든 라 이브 러 리 함 수 를 포함 합 니 다.모든 라 이브 러 리 함 수 는 프로그램 에 연 결 됩 니 다.이러한 프로그램 은 완전한 것 으로 외부 라 이브 러 리 의 지원 이 필요 하지 않 습 니 다.정적 링크 프로그램의 장점 중 하 나 는 설치 하기 전에 환경 준 비 를 하지 않 아 도 된다 는 것 이다.Linux 에서 정적 라 이브 러 리 의 확장 자 는 보통.a 입 니 다.대상 파일(o)의 압축 파일(archive)이나 포장 일 뿐 입 니 다.또한 링크 를 할 때 그 중의 기호(함수,변수 이름 등)를 신속하게 찾 을 수 있 도록 정적 라 이브 러 리 에는 그 중의 기호 에 대한 색인 도 포함 되 어 있 습 니 다.정적 라 이브 러 리 를 만 드 는 과정 은 매우 간단 합 니 다.컴 파일 에 필요 한 도 구 를 제외 하고 사용 할 명령 은 두 개의 AR 과 ranlib 만 있 습 니 다.AR 은 각 대상 파일 을 압축 파일 할 수 있 습 니 다.ranlib 는 AR 에서 생 성 된 압축 파일(즉 정적 라 이브 러 리 파일)을 색인 할 수 있 습 니 다.현재 몇 개의 원본 파일 이 있다 고 가정 합 니 다:plus.c,sub.c 및 해당 하 는 헤더 파일,그리고 라 이브 러 리 파일 의 함 수 를 호출 하 는 메 인 파일 main.c 가 있 습 니 다.그들의 내용 은 각각 plus.c 입 니 다.
#include "plus.h"
int
plus(int a, int b)
{
return a + b;
}
sub.c,
#include "sub.h"
int
sub(int a, int b)
{
return a - b;
}
main.c,
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "plus.h"
int
main(int argc, char **argv)
{
int a = plus(1, 2);
printf("%d
", a);
return 0;
}
다음은 plus.c 와 sub.c 를 컴 파일 하여 정적 라 이브 러 리 libmath.a 로 만 들 고 순서대로 실행 합 니 다.
$ cc main.c -L. -lmath -o main
$ ./main
동적 연결 라 이브 러 리
동적 라 이브 러 리 는 정적 라 이브 러 리 와 비슷 하고 각 대상 파일 의 집합 이기 도 합 니 다.그러나 정적 링크 프로그램 에 비해 동적 링크 는 실행 가능 한 프로그램 이 훨씬 작 습 니 다.이러한 프로그램 이 실 행 될 때 외부 공유 함수 라 이브 러 리 의 지원 이 필요 하기 때문에 완전 하지 않 은 것 같 습 니 다.프로그램 체 가 작은 것 을 제외 하고 동적 링크 는 패키지 가 필요 한 라 이브 러 리 를 지정 할 수 있 으 며 라 이브 러 리 를 패키지 에 불 러 올 필요 가 없습니다.동적 링크 기술 은 여러 실행 중인 프로그램 이 하나의 라 이브 러 리 를 공유 하도록 허용 합 니 다.그러면 같은 코드 의 여러 복사 가 메모리 에서 차지 하 는 상황 이 발생 하지 않 습 니 다.이러한 원인 으로 인해 현재 대부분의 프로그램 은 동적 링크 기술 을 사용한다.리 눅 스에 서 의 확장 자 는 보통.so 입 니 다.그러나 링크 를 연결 할 때 실행 가능 한 파일 에 연결 되 지 않 고 실행 할 때(필요 할 때)운영 체제 의 동적 로드 모듈 에서 메모리 로 동적 으로 불 러 오고 실행 가능 한 파일 주소 공간의 해당 위치 로 연결 합 니 다.동적 링크 라 이브 러 리 의 생 성 도 컴 파일 과 압축 파일 두 단계 로 나 뉘 지만 이 두 단계 에서 서로 다른 명령 옵션 을 사용 해 야 합 니 다.우선,원본 파일 을 위치 와 무관 한 코드(PIC:Position Independent Code)가 되 는 대상 파일 로 컴 파일 해 야 합 니 다.이 코드 는 메모리 의 어느 위치 에 도 추가 할 수 있 지만,추가 장치 가 필요 하지 않 습 니 다.이러한 형식 에 대해 서 는 와 에서 비교적 상세 한 설명 을 참고 할 수 있다.다음은 이 위치 와 상 관 없 이'압축 파일'을'so 파일'로 해 야 합 니 다.전체 과정 은 하나의 도구 만 있 으 면 됩 니 다.즉,gcc 입 니 다.위의 원본 파일 인지 다음 명령 을 수행 합 니 다.
$ cc -c -fpic plus.c sub.c
$ cc -shared -o libmath.so *.o
이렇게 해서 plus.o 와 sub.o 를 포함 하 는 동적 라 이브 러 리 파일 libmath.so 가 만 들 어 졌 습 니 다.그 중에서 cc(gcc 의 심 볼 릭 링크)명령 의-fpic 또는-fpic 옵션 은 위치 와 무관 한 대상 파일 을 만 들 고-shared 옵션 을 사용 하면 최종 동적 라 이브 러 리 파일 을 만 들 수 있 습 니 다.동적 라 이브 러 리 파일 을 사용 하 는 방법 은 두 가지 가 있 습 니 다.하 나 는 운영 체제 의 동적 로드 모듈(예 를 들 어 ld-linux.so.2)을 실행 할 때 동적 라 이브 러 리 를 불 러 오 는 것 입 니 다.다른 하 나 는 코드 에서 dl 라 이브 러 리 동적 로드 라 이브 러 리 파일 을 사용 하 는 것 입 니 다.먼저 다음 방법 을 소개 하 겠 습 니 다.이 방법 을 사용 하려 면 실행 가능 한 파일 을 컴 파일 할 때 라 이브 러 리 이름과 경 로 를 알려 야 합 니 다.(자신 이 작성 한 동적 라 이브 러 리 에 대해 서 는)
$ cc main.c -L. -lmath -o main
이 때 실행 가능 한 파일 main 이 생 성 되 었 습 니 다.위의 명령 은 libmath.so 에 해당 하 는 대상 코드 를 main 에 연결 하지 않 았 습 니 다.(main 과 정적 링크 의 main 크기 를 비교 해 볼 수 있 습 니 다)라 이브 러 리 에서 main.c 에 사용 되 는 기 호 를 찾 고 확인 할 수 있 습 니 다.그러나 이 main 은 현재 정상적으로 실행 되 지 않 습 니 다.이것 은 시스템 이 동적 라 이브 러 리 를 찾 는 경로 문제 와 관련 되 어 있 습 니 다.시스템 은 보통 지정 한 디 렉 터 리(표준 경로)에서 필요 한 라 이브 러 리 파일 만 찾 습 니 다.표준 경로 에서 필요 한 라 이브 러 리 를 찾 을 수 없 으 면 환경 변 화 량 LD 로 갑 니 다.LIBRARY_PATH(존재 한다 면)가 지정 한 디 렉 터 리 에서 찾 습 니 다.찾 을 수 없 으 면 오류 가 발생 합 니 다.libmath.so 는 main 의 현재 디 렉 터 리 에 있 기 때문에 현재 디 렉 터 리 는 표준 경로 의 열 에 있 지 않 습 니 다.libmath.so 를 찾 고 불 러 올 수 있 도록 표준 경로 에 넣 을 수 있 지만 더 좋 은 방법 은 해당 디 렉 터 리 를 LD 에 추가 하 는 것 입 니 다.LIBRARY_PATH 변수 중.다음 명령 실행:
$ LD_LIBRARY_PATH=$LD_LIBRARY_PATH:. #
$ export LD_LIBRARY_PATH # , shell
$ ./main
3
다음은 dl 라 이브 러 리 를 사용 하여 동적 라 이브 러 리 를 불 러 옵 니 다.dl 라 이브 러 리 의 함수 가 매우 간결 하지 않 습 니 다.main.c 코드 를 보십시오.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dlfcn.h>
#include "plus.h"
int
main(int argc, char **argv)
{
void * lib_handle = dlopen("./libmath.so", RTLD_LAZY);
if(lib_handle)
{
int (*plus_ptr)(int, int) = dlsym(lib_handle, "plus");
if(plus_ptr)
{
int a = plus_ptr(1, 2);
printf("%d
", a);
}
dlclose(lib_handle);
}
return 0;
}
main.c 에서 먼저 dlopen 을 사용 하여 필요 한 동적 라 이브 러 리 를 엽 니 다.그 중에서 매개 변 수 는 RTLD 입 니 다.레이 지 는 이 라 이브 러 리 를 호출 해 야 할 때 만 불 러 옵 니 다.dlopen 은 핸들 을 되 돌려 줍 니 다.dlsym 은 이 핸들 과 기 호 를 사용 하여 해당 함수 의 주 소 를 얻 습 니 다.여 기 는 int(*)(int,int)함수 포인터 로 plus 함수 의 주 소 를 받 습 니 다.다음 에 얻 은 함수 포인터 로 해당 함 수 를 호출 하고 마지막 으로 dlclose 함 수 를 통 해 핸들 을 닫 습 니 다.이 프로그램 을 컴 파일 하려 면 dl 동적 링크 라 이브 러 리 를 사용 해 야 하기 때문에 gcc-ldl 옵션 을 사용 해 야 합 니 다.
$ cc main.c -ldl -o main
$ ./main
so 와 a 파일 의 대비
마지막 으로 libmath.a 와 libmath.so 파일 의 내용 을 첨부 하고 objdump 의-d 옵션 을 사용 하여 보 았 습 니 다:libmath.a,
In archive libmath.a:
plus.o: file format elf32-i386
Disassembly of section .text:
00000000 <plus>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 8b 45 0c mov 0xc(%ebp),%eax
6: 8b 55 08 mov 0x8(%ebp),%edx
9: 8d 04 02 lea (%edx,%eax,1),%eax
c: 5d pop %ebp
d: c3 ret
sub.o: file format elf32-i386
Disassembly of section .text:
00000000 <sub>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 8b 45 0c mov 0xc(%ebp),%eax
6: 8b 55 08 mov 0x8(%ebp),%edx
9: 89 d1 mov %edx,%ecx
b: 29 c1 sub %eax,%ecx
d: 89 c8 mov %ecx,%eax
f: 5d pop %ebp
10: c3 ret
libmath.so:
libmath.so: file format elf32-i386
Disassembly of section .init:
00000324 <_init>:
324: 55 push %ebp
325: 89 e5 mov %esp,%ebp
327: 53 push %ebx
328: 83 ec 04 sub $0x4,%esp
......
0000044c <plus>:
44c: 55 push %ebp
44d: 89 e5 mov %esp,%ebp
44f: 8b 45 0c mov 0xc(%ebp),%eax
452: 8b 55 08 mov 0x8(%ebp),%edx
455: 8d 04 02 lea (%edx,%eax,1),%eax
458: 5d pop %ebp
459: c3 ret
45a: 90 nop
45b: 90 nop
0000045c <sub>:
45c: 55 push %ebp
45d: 89 e5 mov %esp,%ebp
45f: 8b 45 0c mov 0xc(%ebp),%eax
462: 8b 55 08 mov 0x8(%ebp),%edx
465: 89 d1 mov %edx,%ecx
467: 29 c1 sub %eax,%ecx
469: 89 c8 mov %ecx,%eax
46b: 5d pop %ebp
46c: c3 ret
46d: 90 nop
46e: 90 nop
46f: 90 nop
......
Disassembly of section .fini:
000004a8 <_fini>:
4a8: 55 push %ebp
4a9: 89 e5 mov %esp,%ebp
4ab: 53 push %ebx
4ac: 83 ec 04 sub $0x4,%esp
4af: e8 00 00 00 00 call 4b4 <_fini+0xc>
4b4: 5b pop %ebx
4b5: 81 c3 40 1b 00 00 add $0x1b40,%ebx
4bb: e8 d0 fe ff ff call 390 <__do_global_dtors_aux>
4c0: 59 pop %ecx
4c1: 5b pop %ebx
4c2: c9 leave
4c3: c3 ret
이 를 통 해 알 수 있 듯 이 상대 적 으로 a,so 에는 많은 추가 코드 세그먼트 가 있 는데 그 중에서 비교적 중요 한 것 은
다음으로 이동:http://www.dutor.net/index.php/2010/07/dynamic-static-library/
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Visual Studio에서 파일 폴더 구분 (포함 경로 설정)Visual Studio에서 c, cpp, h, hpp 파일을 폴더로 나누고 싶었습니까? 어쩌면 대부분의 사람들이 있다고 생각합니다. 처음에 파일이 만들어지는 장소는 프로젝트 파일 등과 같은 장소에 있기 때문에 파일...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.