Tạo và Sử dụng Thư viện - Thư viện Tĩnh và Thư viện Động

Tạo và Sử dụng Thư viện - Thư viện Tĩnh và Thư viện Động

I. Giới thiệu Thư viện

Thư viện là các tệp tin trong lập trình máy tính được sử dụng để lưu trữ các biến, hàm và lớp, cung cấp cho các nhà phát triển tài nguyên có thể sử dụng ngay lập tức. Thư viện được chia thành hai loại chính: thư viện tĩnh và thư viện động, khác nhau về cách thức hoạt động trong giai đoạn liên kết của chương trình:

  • Thư viện tĩnh: Trong giai đoạn liên kết, nội dung của thư viện được sao chép vào chương trình. Mỗi khi chương trình chạy, nội dung của thư viện tĩnh được sao chép hoàn toàn, do đó chiếm nhiều bộ nhớ hơn, nhưng không phụ thuộc vào các tệp bên ngoài, phù hợp cho việc phân phối độc lập.
  • Thư viện động: Trong giai đoạn liên kết, nội dung của thư viện không được sao chép vào chương trình, mà được hệ thống tải động vào bộ nhớ khi chương trình chạy. Nhiều chương trình có thể chia sẻ một phiên bản của thư viện động, tiết kiệm bộ nhớ và dễ dàng cập nhật theo mô-đun.

1.1 Sự khác biệt giữa Thư viện Tĩnh và Thư viện Động

  • Thư viện tĩnh:

  • Trong quá trình biên dịch, nội dung của thư viện được sao chép vào chương trình.

  • Ưu điểm: Không cần lo lắng về việc thiếu thư viện khi chạy chương trình.

  • Nhược điểm: Chiếm nhiều bộ nhớ hơn, khó cập nhật.

  • Giống như một hiệu sách, chỉ bán không cho mượn.

  • Thư viện động:

  • Được tải trong thời gian chạy, không được sao chép vào chương trình trong quá trình biên dịch.

  • Ưu điểm: Tiết kiệm bộ nhớ, tăng hiệu suất thực thi chương trình.

  • Nhược điểm: Cần hỗ trợ thư viện động trong thời gian chạy.

  • Giống như thư viện công cộng, chỉ cho mượn không bán.

1.2 Quy tắc đặt tên Thư viện

  • Tiền tố lib: ví dụ libDeployPkg.so.0
  • Thư viện tĩnh có đuôi .a
  • Thư viện động có đuôi .so
  • Số phiên bản sau đuôi: ví dụ libc.so.1.0.3

libc.so.1.0.3 lib - Tiền tố của tệp thư viện c - Tên thư viện (khi liên kết thư viện, chỉ cần viết tên này) .so - Đuôi (so là thư viện động/chia sẻ, a là thư viện tĩnh) .1 - Phiên bản thư viện .0.3 - Số sửa đổi

II. Tạo Thư viện

Nguyên liệu để tạo cả thư viện tĩnh và thư viện động là các tệp .o (tệp có thể tái định vị), các tệp này không thể chứa hàm chính main.

2.1 Tạo Thư viện Tĩnh

  1. Tạo tệp .o:
gcc -c -fPIC -I../inc hoanvi.c -o hoanvi.o
gcc -c -fPIC -I../inc max.c -o max.o
  • -c: Tạo tệp có thể tái định vị và dừng.
  • -fPIC: Tạo tệp thực thi không phụ thuộc vào địa chỉ.

Lựa chọn fPIC: Nếu không sử dụng -fPIC, khi tải đoạn mã của tệp .so, các đối tượng dữ liệu mà đoạn mã tham chiếu cần được tái định vị. Tái định vị sẽ sửa đổi nội dung đoạn mã, điều này gây ra mỗi tiến trình sử dụng đoạn mã của tệp .so này sẽ tạo một bản sao trong kernel. Mỗi bản sao đều khác nhau, phụ thuộc vào vị trí ánh xạ bộ nhớ của đoạn mã và đoạn dữ liệu của tệp .so này.

  1. Tạo tệp thư viện tĩnh:
ar -rcs libmy_lib.a hoanvi.o max.o

rcs là các tham số để tạo tệp thư viện tĩnh:

  • r: Thay thế tệp đã tồn tại.
  • c: Tạo thư viện mới.
  • s: Tạo chỉ mục, tăng tốc độ tìm kiếm trong tệp thư viện.
  1. Sử dụng tệp thư viện tĩnh:
gcc src/*.c -I./inc -L./lib -lmy_lib -o bin/chinh

-I: Chỉ định đường dẫn tệp header, -L: Chỉ định đường dẫn tệp thư viện, -l: Chỉ định tên thư viện, -o: Chỉ định tên tệp thực thi (đường dẫn).

2.2 Tạo Thư viện Động

  1. Tạo tệp .o:
gcc -c -fPIC -I../inc hoanvi.c -o hoanvi.o
gcc -c -fPIC -I../inc max.c -o max.o
  1. Tạo tệp thư viện động:
gcc -shared -fPIC -o libmy_lib.so.0 hoanvi.o max.o

-shared: Tạo tệp thư viện động -fPIC: Tạo tệp thực thi không phụ thuộc vào địa chỉ -o: Chỉ định tên tệp thư viện động (đường dẫn)

  1. Tạo liên kết mềm cho tệp thư viện động:
ln -s libmy_lib.so.0 libmy_lib.so

Lưu ý: Liên kết mềm không bắt buộc, nhưng trong quản lý phiên bản, chúng ta thường cần tạo liên kết mềm cho mỗi phiên bản của thư viện để dễ dàng quản lý. Tại sao cần tạo liên kết mềm?

  • Quản lý phiên bản: Phiên bản của thư viện động liên tục được cập nhật, ví dụ từ libmy_lib.so.0 lên libmy_lib.so.1. Bằng cách sử dụng liên kết mềm, bạn có thể chỉ định libmy_lib.so đến phiên bản mới nhất mà không cần sửa đổi mã hoặc biên dịch lại.
  • Tiện lợi khi biên dịch: Bộ biên dịch và liên kết thường tìm kiếm tên thư viện không có số phiên bản (ví dụ libmy_lib.so), sau đó tự động liên kết đến thư viện tương ứng. Nếu không có liên kết mềm, bộ biên dịch có thể không tìm thấy thư viện, dẫn đến lỗi biên dịch.
  • Đơn giản hóa việc sử dụng: Liên kết mềm cho phép bạn viết Makefile hoặc các kịch bản biên dịch khác đơn giản hơn, không cần quan tâm đến số phiên bản cụ thể của tệp thư viện.
  1. Sử dụng tệp thư viện động:
  • Biên dịch:
gcc src/*.c -I./inc -L./lib -lmy_lib -o bin/chinh
  • Chạy:
./chinh
2.2.1 Vấn đề tải thư viện động và cách giải quyết

Sử dụng trực tiếp sẽ báo lỗi:

./chinh: error while loading shared libraries: libmy_lib.so: cannot open shared object file: No such file or directory

Lý do: Khi chạy chương trình, thư viện động cần được tải vào bộ nhớ, hành động này do hệ thống thực hiện. Hệ thống không biết thư viện của chúng ta ở đâu, do đó việc tải thất bại.

  1. Phương pháp 1: Đặt tệp thư viện vào đường dẫn mặc định của hệ thống (khuyến nghị). -> /usr/lib/ hoặc /lib
sudo cp lib/libmy_lib.so /usr/lib/
  1. Phương pháp 2: Thêm đường dẫn thư viện vào biến môi trường.
vim ~/.bashrc

Thêm vào cuối:

export LD_LIBRARY_PATH=/home/user/thu_vien_cua_toi:$LD_LIBRARY_PATH

LD_LIBRARY_PATH là một biến môi trường, được sử dụng để chỉ định đường dẫn tìm kiếm thư viện liên kết động. Khi chương trình chạy, hệ thống sẽ tìm kiếm theo đường dẫn này để tìm thư viện liên kết động. : là dấu phân cách, $LD_LIBRARY_PATH biểu thị đường dẫn ban đầu.

Tải lại tệp cấu hình:

source ~/.bashrc
  1. Phương pháp 3: Thêm đường dẫn mới vào đường dẫn mặc định của hệ thống.
sudo vim /etc/ld.so.conf.d/libc.conf

Thêm đường dẫn thư viện:

/home/user/thu_vien_cua_toi

Tải lại cấu hình:

sudo ldconfig

Lưu ý: Nếu thư viện động và thư viện tĩnh có cùng tên và được đặt cùng một chỗ, bộ biên dịch sẽ mặc định sử dụng liên kết động. Cách chỉ định cho bộ biên dịch sử dụng thư viện tĩnh: -static

2.3 Tùy chọn biên dịch tĩnh

  • Chỉ định sử dụng thư viện tĩnh:
gcc src/*.c -o bin/chinh -L./lib -I./inc -lmy_lib -static

III. Ẩn đường dẫn dòng lệnh

Đường dẫn ở trên quá dài, có thể ẩn đi:

  1. Chỉnh sửa .bashrc:
vim ~/.bashrc
  1. Thêm nội dung sau:
export PS1='[\u@\h \W]\$ '
  1. Tải lại tệp cấu hình:
source ~/.bashrc

Thẻ: thư viện tĩnh thư viện động gcc lập trình C liên kết tĩnh

Đăng vào ngày 24 tháng 6 lúc 10:36