2010-07-01 25 views
5

Bài đăng đầu tiên của tôi trên trang này với hy vọng lớn :: Tôi đang cố gắng hiểu liên kết tĩnh, liên kết động, thư viện được chia sẻ, thư viện tĩnh, v.v. Mỗi lần tôi cố gắng nghiên cứu chủ đề này, tôi có một thứ mà tôi không hiểu lắm.trong gcc cách ép buộc độ phân giải biểu tượng tại thời gian chạy

Một số thực hành công việc:

bash$ cat main.c 

#include "printhello.h" 
#include "printbye.h" 

void main() 
{ 
PrintHello(); 
PrintBye(); 
} 

bash$ cat printhello.h 
void PrintHello(); 

bash$ cat printbye.h 
void PrintBye(); 

bash$ cat printbye.c 
#include <stdio.h> 

void PrintBye() 
{ 
printf("Bye bye\n"); 
} 

bash$ cat printhello.c 
#include <stdio.h> 

void PrintHello() 
{ 
printf("Hello World\n"); 
} 

gcc -Wall -fPIC -c *.c -I. 
gcc -shared -Wl,-soname,libcgreet.so.1 -o libcgreet.so.1.0 *.o 
ln -sf libcgreet.so.1.0 libcgreet.so 
ln -sf libcgreet.so.1.0 libcgreet.so.1 

Vì vậy, tôi đã tạo ra một thư viện chia sẻ. Bây giờ tôi muốn liên kết thư viện được chia sẻ này với chương trình chính của tôi để tạo một tệp thực thi.

gcc -Wall -L. main.c -lcgreet -o greet

Nó rất tốt hoạt động và nếu tôi đặt LD_LIBRARY_PATH trước khi chạy chào (hoặc liên kết nó với tùy chọn rPath) tôi có thể làm cho nó hoạt động. Tuy nhiên, câu hỏi của tôi có thể khác nhau: Vì tôi vẫn sử dụng thư viện được chia sẻ, nên không thể buộc độ phân giải biểu tượng trong thời gian chạy (không chắc về thuật ngữ nhưng có thể được gọi là liên kết động theo sách "Trình liên kết và Trình tải") . Tôi hiểu rằng chúng tôi có thể không muốn làm điều đó bởi vì điều này làm cho chương trình chạy chậm và có chi phí mỗi khi chúng tôi muốn chạy chương trình, nhưng tôi đang cố gắng hiểu điều này để xóa các khái niệm của mình.

Trình liên kết gcc có cung cấp bất kỳ tùy chọn nào để trì hoãn độ phân giải biểu tượng khi chạy không? (để làm điều đó với thư viện chúng tôi thực sự sẽ chạy chương trình với) (như thư viện có sẵn tại thời gian biên dịch có thể khác với thư viện có sẵn trong thời gian chạy nếu có bất kỳ thay đổi nào trong thư viện) Tôi muốn có thể làm như vậy :

bash $ gcc main.c -I.

(tùy chọn cần thiết ở đây?) để tôi không phải đặt tên thư viện và chỉ cần nói rằng tôi muốn thực hiện độ phân giải biểu tượng trong thời gian chạy, vì vậy tiêu đề đủ tốt cho hiện tại không cần thiết.

Xin cảm ơn, Người học cho mãi mãi.

+0

http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html – adf88

+0

Đảm bảo rằng bạn gắn thẻ câu hỏi bằng ngôn ngữ thích hợp. Nó được gắn thẻ là C++, nhưng mã là C. Lưu ý rằng để có thể sử dụng thư viện động thuần túy tải mã trong C++ sẽ cần chứa thêm 'extern" C "' rắc xung quanh mà không cần thiết cũng không hợp lệ trong C. –

Trả lời

9

Bất kỳ trình liên kết nào (gcc, ld hoặc bất kỳ cách nào khác) chỉ giải quyết các liên kết tại thời gian biên dịch. Đó là bởi vì tiêu chuẩn ELF (như hầu hết những người khác) không định nghĩa liên kết 'thời gian chạy' khi bạn mô tả. Chúng liên kết tĩnh (ví dụ: lib.a) hoặc lúc khởi động (lib.so, phải có khi ELF được tải). Tuy nhiên, nếu bạn sử dụng liên kết động, trình liên kết sẽ chỉ đưa vào ELF tên của tệp và các ký hiệu phải tìm, nó không liên kết trực tiếp tệp. Vì vậy, nếu bạn muốn nâng cấp lib lên phiên bản mới hơn sau đó, bạn có thể làm như vậy, miễn là hệ thống có thể tìm cùng tên tệp (đường dẫn có thể khác nhau) và cùng tên biểu tượng.

Tùy chọn khác, để nhận biểu tượng trong thời gian chạy, là sử dụng dlopen, không có liên quan gì với gcc hoặc ld. dlopen chỉ cần đặt, mở thư viện liên kết động, giống như fopen có thể và trả về cho bạn một xử lý, sau đó bạn chuyển đến dlsym với tên của biểu tượng bạn muốn, có thể là tên hàm chẳng hạn. dlsym sau đó sẽ chuyển cho bạn một con trỏ đến biểu tượng đó, sau đó bạn có thể sử dụng để gọi hàm hoặc sử dụng làm biến. Đây là cách bổ sung được thực hiện.

+0

1 cho câu trả lời hay và chỉ ra các plugin. – stinky472

+1

Trong trường hợp thẻ ngôn ngữ C++ là chính xác, hãy nhớ đánh dấu các ký hiệu là 'extern" C "' để chúng không bị xáo trộn vào thời gian biên dịch. –

1

Tôi nghĩ bạn đang tìm tùy chọn ld '--unresolved-symbols = ignore-all', có nó thực sự có thể làm điều đó (bỏ qua câu trả lời trước).Hãy tưởng tượng kịch bản mà một thư viện chia sẻ được tải trễ (khi chương trình đang chạy), nó có thể sử dụng tất cả các biểu tượng đã được giải quyết/tải bởi quá trình chính, không cần phải bận tâm để làm điều đó một lần nữa. btw nó không lo lắng làm cho nó chậm, ít nhất là trên Linux

Các vấn đề liên quan