Hệ thống Dlopen Linux trong C

He Thong Dlopen Linux Trong C



Hàm thư viện dlopen () là một hàm rất hữu ích trong ngôn ngữ C. Hàm tải thư viện vào bộ nhớ sau khi mở một thư viện mới. Chúng tôi thường sử dụng nó để tải các ký hiệu thư viện chưa biết tại thời điểm biên dịch. Dlopen () là một hàm được sử dụng trong các chương trình của chúng tôi. Thư viện DL thực hiện dlopen (), được định nghĩa trong Dlfcn.h. Hai tham số được yêu cầu cho hàm dlopen: tên của tệp thư viện và cờ. Tên của tệp là một thư viện động và nó xác định liệu các phần phụ thuộc của thư viện có được tính toán ngay hay không. Dlopen () trả về một “xử lý” nên được coi là một giá trị không rõ ràng và các hoạt động thư viện DL khác sử dụng giá trị này. Nếu cố gắng tải không thành công, dlopen () trả về NULL. Nhưng dlopen () trả về cùng một tệp xử lý nếu nó tải cùng một thư viện nhiều lần.

Trong khi sử dụng hàm dlopen, trình biên dịch không kiểm tra các lỗi tiềm ẩn vì nó không biết về các loại và nguyên mẫu mà chúng ta đang sử dụng. Việc triển khai hàm dlopen để tải tiêu chuẩn dường như không được thúc đẩy bởi nó, ngoại trừ một vài tình huống nhỏ. Nhân tiện, đó là một cách tiếp cận để cải thiện khả năng xem xét nội tâm. Khi mô-đun được chia sẻ hiện đang được sử dụng bởi một chương trình khác, việc tối ưu hóa bố cục bộ nhớ không đặc biệt quan tâm đến tải có điều kiện. Dấu chân bộ nhớ không tăng khi một thư viện đã sử dụng trước đó được tải. Tránh giám sát trình biên dịch là nguy hiểm và tạo ra lỗi tốt. Ngoài ra, chúng tôi thiếu khả năng tối ưu hóa trình biên dịch.

Ví dụ 1:

Bây giờ, hãy xem xét ví dụ sau để xem chức năng của hàm dlopen trong ngôn ngữ C. Trong bước đầu tiên, chúng tôi tải một số thư viện tiêu chuẩn C. Ở đây, chúng tôi tải thư viện mới “dlfcn.h” được sử dụng để xác định các macro trong khi xây dựng đối số chế độ dlopen.







Sau đó, chúng tôi giới thiệu một thư viện khác bên trong chương trình của chúng tôi “gnu / lib-name.h”. Các tệp thư viện chia sẻ đi kèm với GNU libc được tìm thấy bởi các chương trình người dùng theo các macro mà nó định nghĩa. Thư viện GNU C cung cấp các thư viện cơ bản cho hệ điều hành GNU và GNU / Linux cũng như một loạt các hệ thống dựa trên Linux khác. Sau đó, chúng ta có phương pháp thực hiện chính. Bên trong đó, chúng ta khai báo đối tượng con trỏ “handle” với từ khóa void. Chúng ta khai báo một hàm sin con trỏ có kiểu dữ liệu double. Có một khai báo khác về đối tượng con trỏ 'error' để xử lý lỗi.



Sau đó, chúng ta gọi hàm dlopen bên trong đối tượng “handle”. Dlopen nhận hai đối số: LIBM_SO và “RTLD_LAZY”. Ở đây, “LIBM_SO” là tên của tệp thư viện cung cấp các hàm toán học như hàm lượng giác. Thư viện được chia sẻ này là bắt buộc khi chúng tôi sử dụng hàm sin. “RTLD_LAZY” là một đối số khác gọi hàm dlopen. Khi một biểu tượng nhất định được tham chiếu lần đầu tiên, việc chuyển vị trí phải được thực hiện tại một thời điểm được xác định bởi việc triển khai.



Vì một quy trình có thể không tham chiếu đến mọi ký hiệu trong tệp đối tượng thực thi, việc chỉ định RTLD LAZY sẽ nâng cao hiệu suất trên các triển khai cho phép liên kết ký hiệu động. Tiếp theo, chúng ta có một điều kiện if-else để xử lý lỗi khi đối tượng xử lý không thực hiện được hàm dlopen. Chúng tôi gọi thợ sửa lỗi để xóa lỗi.





Hàm dlerror () cung cấp một chuỗi được kết thúc bằng null mà con người có thể đọc được và chỉ định báo cáo về lỗi gần đây gây ra bởi một lệnh gọi đến một trong các lệnh gọi API dlopen kể từ lần gọi dlerror cuối cùng. Sau đó, chúng ta ép kiểu hàm như sau: “(* void **) (& sine) = dlsym (handle, sin)”. Vì điều này thật kỳ lạ, quá trình truyền tuân theo ISO C để tránh các cảnh báo từ trình biên dịch. Chúng tôi sử dụng hàm dlsym lấy đường dẫn của một ký hiệu được chỉ định bên trong một mô-đun liên kết động có thể truy cập thông qua một hàm dlopen ().

Ngoài ra, chúng tôi thực hiện lại thao tác if-else đối với lỗi chuẩn được tạo ra khi lỗi dlerror () không phải là NULL. Sau đó, chúng ta có một câu lệnh printf trong đó chúng ta chỉ định giá trị sin sẽ được tính toán. Trong bước cuối cùng, chúng tôi đóng đối tượng được chia sẻ đó bằng cách gọi dlclose cho xử lý được trả về bởi dlopen ().



#include
#include
#include
#include

int
chính ( int argc , char ** argv )
{
vô hiệu * xử lý ;
kép ( * của họ ) ( kép ) ;
char * lỗi ;

xử lý = dlopen ( LIBM_SO , RTLD_LAZY ) ;
nếu ( ! xử lý ) {
fprintf ( stderr , '%S \N ' , dlerror ( ) ) ;
lối ra ( EXIT_FAILURE ) ;
}
dlerror ( ) ;

* ( vô hiệu ** ) ( & của họ ) = dlsym ( xử lý , 'không có' ) ;

nếu ( ( lỗi = dlerror ( ) ) ! = VÔ GIÁ TRỊ ) {
fprintf ( stderr , '%S \N ' , lỗi ) ;
lối ra ( EXIT_FAILURE ) ;
}

printf ( '% f \N ' , ( * của họ ) ( 4.0 ) ) ;
dlclose ( xử lý ) ;
lối ra ( EXIT_SUCCESS ) ;
}

Chúng tôi sử dụng tùy chọn -ldl với lệnh biên dịch C vì đây là thư viện cho giao diện liên kết dlopen và nó là bắt buộc. Khi thực thi tệp dlopen được thực hiện, nó sẽ hiển thị giá trị sin của giá trị đã cho trước đó.

Ví dụ 2:

Bây giờ, chúng ta lấy một ví dụ khác về việc sử dụng hàm dlopen. Chúng tôi tải chương trình của mình với tất cả các thư viện C cần thiết để triển khai mã dlopen. Sau đó, chúng tôi bắt đầu chương trình của mình bên trong phương thức chính. Ở đây, chúng tôi xác định chuỗi với khai báo của biến “src”. Sau đó, chúng tôi khai báo các biến con trỏ “strlen”, “xử lý” và “lỗi”.

Tiếp theo, chúng ta gọi biến xử lý và triển khai hàm dlopen. Hàm dlopen nhập thư viện chia sẻ “libstr.so” cho các hàm xử lý chuỗi và cờ “RTLD_LAZY” đã được minh họa trong ví dụ trước. Chúng tôi gọi hàm dlerror bên trong biến 'error' để xóa lỗi do hàm dlopen tạo ra. If-else được sử dụng để kiểm tra các lỗi.

Sau đó, chúng tôi lấy địa chỉ của hàm strlen bằng cách sử dụng hàm dlsym và xác minh các lỗi trong khi thực hiện việc này. Sau đó, chúng ta sử dụng hàm printf để gọi hàm strnlen để trả về độ dài của chuỗi đã cho. Cuối cùng, chúng tôi đóng thư viện được chia sẻ bằng hàm dlclose.

#include
#include
#include
#include
int chính ( vô hiệu )
{
char * src = 'Xin chào Linux' ;
int ( * strlen ) ( hăng sô char * ) ;
vô hiệu * xử lý ;
char * lỗi ;


xử lý = dlopen ( './libstr.so' , RTLD_LAZY ) ;
lỗi = dlerror ( ) ;
nếu ( ! xử lý || lỗi ! = VÔ GIÁ TRỊ ) { printf ( 'Tải Thư viện Cố gắng Không thành công! \N %S \N ' , lỗi ) ;
trở về - 1 ; }

strlen = dlsym ( xử lý , 'strlen' ) ;
lỗi = dlerror ( ) ;
nếu ( ! strlen || lỗi == VÔ GIÁ TRỊ ) { printf ( '%S \N ' , lỗi ) ; trở về - 1 ; }

printf ( 'Chiều dài của Chuỗi là:% d \N ' , strlen ( src ) ) ;
dlclose ( xử lý ) ;
trở về 0 ;
}

Chúng tôi sử dụng lệnh sau để thực hiện chương trình đã cho. Ở đây, cờ -lstr được sử dụng cho hàm độ dài chuỗi và ldl được sử dụng cho tệp thư viện dlopen. Chương trình đã biên dịch cung cấp độ dài của chuỗi như được hiển thị trong shell:

Sự kết luận

Thông tin được cung cấp liên quan đến chức năng dlopen của ngôn ngữ C trong bài viết này. Chúng tôi có một giới thiệu ngắn gọn về hàm dlopen. Sau đó, chúng tôi thực hiện hai ví dụ. Hàm trả về một mã định danh xác định thư viện đã mở. Địa chỉ của các hàm bên trong thư viện đã mở sau đó được xác định bằng cách sử dụng mã định danh này và hàm dlsym. Bạn có thể tìm thấy địa chỉ của một hàm trong thư viện đã được mở bằng dlopen bằng cách sử dụng hàm dlsym.