2014-05-06 16 views
5

Bạn có nhớ để lại nhận xét của mình về điều này nếu bạn có thực sự có kinh nghiệm liên quan đến tiêu đề ở trên không? Tôi đã cố gắng để làm cho một đối tượng được chia sẻ để được trì hoãn tải với cả Clang và GCC trên Ubuntu (tôi thực sự không nhớ trình biên dịch được sử dụng), nhưng họ không thực sự hỗ trợ bất kỳ tính năng tải chậm trễ (tôi mong đợi tính năng tải chậm trễ đặt một sơ khai trong một đối tượng cha mẹ, mà đã cố gắng để tải một đối tượng khác theo yêu cầu, tại một thời điểm khi chức năng được yêu cầu, nhưng nó thực sự không). Các lệnh sau đây cho thấy rằng tôi đã cố gắng để làm cho libbar.so được nạp trễ so với libfoo.so:Clang/GCC có thực sự hỗ trợ tính năng tải chậm không?

clang bar.c -fPIC -shared -o libbar.so 
clang foo.c -Wl,-zlazy,lL'/path/to/where/lib/is',-lbar -o foo 

Bạn sẽ thấy libfoo.so nâng một ngoại lệ trước khi vào đến mục nếu libbar.so làm không tồn tại. Dù sao, tôi không nhớ nếu có bất kỳ lỗi đánh máy nào trong các lệnh trên, nhưng muốn biết Clang/GCC thực sự hỗ trợ tính năng tải chậm trễ hoặc không.

Cá nhân, tuy nhiên, tôi không thể tin rằng nếu các nhà phát triển chương trình Linux đã yêu cầu gọi dlopen() hoặc dlsym() để làm cho một đối tượng được chia sẻ bị trì hoãn tải nếu Clang/GCC không hỗ trợ bất kỳ tính năng tải chậm trễ nào. Nó có thể được okay nếu đối tượng được viết bằng C, nhưng nếu nó được viết bằng C++, tình hình phải hoàn toàn phức tạp: (

Tôi tin rằng một giải pháp được thực hiện với sự trợ giúp từ trình biên dịch hoặc liên kết là tốt nhất vì Tôi đã thực hiện thành công nó với Windows và Mac OS.Vì vậy, tôi cảm thấy nó sẽ là một phản ứng tự nhiên, nơi công dân muốn ước mơ để có một tính năng tải chậm trễ ngay cả trên Clang/GCC.Tôi cũng sẽ đánh giá cao nếu bạn có bất kỳ bình luận về tôi cảm giác.

PS. tôi biết Solaris hỗ trợ một tính năng chậm trễ bốc nhưng điều đó không phải là một con đường để đi cho tôi bởi vì tôi sẽ không phát triển bất cứ điều gì trên đó.

Dù sao, cảm ơn bạn rất nhiều trước.

+0

Vâng, điều này có thể được thực hiện trên Linux. – kec

+0

@ kec, cảm ơn. Bạn có nghĩa là GCC/Clang có thể làm cho một đối tượng được chia sẻ chậm trễ tải bằng cách đi qua một số tùy chọn cho họ? Có bất kỳ tài liệu chính thức nào mô tả cách sử dụng nó không? Thật tuyệt khi biết bạn có thể giải thích tại sao tôi nhận được kết quả ở trên không. – Doofah

+0

Thực ra, sau khi đọc lại, tôi không chắc tôi biết bạn đang nói về điều gì. Bạn đang nói về dlopen()? Bạn muốn điều gì xảy ra? – kec

Trả lời

10

Đây là câu hỏi về chức năng được cung cấp bởi trình liên kết thời gian chạy, ld-linux.so.

Trình liên kết này không hỗ trợ ràng buộc lười biếng các ký hiệu, nhưng không tải thư viện quá tải. Điều này có nghĩa là mỗi đối tượng được chia sẻ mà một tệp thực thi yêu cầu được nạp khi chương trình khởi động, nhưng các biểu tượng trong chương trình không được giải quyết cho các thư viện đã tải cho đến khi chúng được tham chiếu lần đầu tiên.

Lý do cho điều này là hiệu suất. Một thư viện có thể chứa hàng nghìn biểu tượng cho các hàm không bao giờ được gọi trong một lần thực thi chương trình. Giải quyết tất cả sẽ là một sự lãng phí thời gian.

Vì lý do này, nếu thư viện không chứa ký hiệu mong muốn, bạn có thể gặp lỗi 'biểu tượng không xác định' sau khi chương trình bắt đầu chạy, nhưng nếu thiếu thư viện hoàn toàn, bạn sẽ gặp lỗi trước chương trình bắt đầu.

Tùy chọn -zlazy mà bạn đang trích dẫn chỉ điều khiển biểu tượng lười ràng buộc. Trong thực tế nó được kích hoạt theo mặc định (ít nhất là cho GCC, tôi đã không kiểm tra clang).

Cách duy nhất để có thư viện được tải sau khi khởi động chương trình, ví dụ để phản hồi một số tùy chọn dòng lệnh, cấu hình hoặc điều kiện động khác, là gọi dlopen.

Bạn có thể muốn nhìn xung quanh cho một khuôn khổ plugin tốt - để tham khảo xem:

+0

@ harmic, cảm ơn bạn đã để lại bình luận của bạn. Nó trả lời tất cả những gì tôi đã làm sai. Tôi sẽ đọc các tài liệu tham khảo bạn đã đăng ở trên. Cám ơn bạn một lần nữa! :) – Doofah

+0

@ harmic, lý do tôi do dự để sử dụng cách dlopen là nó trông rất phức tạp để thực hiện. Tôi đã thực sự xác nhận nó hoạt động với một chương trình C++ rất đơn giản (nó gọi một hàm thành viên của một lớp được lấy bởi một con trỏ lớp được trả về từ dlsym()). Nhưng nếu tôi cố gắng áp dụng kỹ thuật này cho thư viện của bên thứ ba (nó phức tạp hơn nhiều so với chương trình hướng dẫn tôi đã thử nghiệm), mọi thứ trở nên điên rồ ... – Doofah

+0

@ user3591878 khó để biết vấn đề là gì từ mô tả đó! Tôi đề nghị bạn đăng nó như một câu hỏi riêng. Bao gồm chương trình mẫu nhỏ nhất mà bạn có thể gây ra hành vi 'điên'. – harmic

0

Linux không hỗ trợ chậm trễ tải các thư viện ra của hộp nhưng nó có thể dễ dàng được thực hiện bằng cách sử dụng cùng một cơ chế được sử dụng trên Windows tức là bằng cách liên kết với stub st nhỏ thư viện atic trong đó dlopen s thư viện được chia sẻ chính trong lần gọi đầu tiên tới bất kỳ chức năng nào của nó.

Bạn có thể thực hiện như thư viện còn sơ khai bằng tay, thông qua kịch bản được điều chỉnh theo cho dự án của bạn hoặc sử dụng Implib.so để tạo ra nó tự động:

$ clang bar.c -fPIC -shared -o libbar.so 
$ gen-implib.py libbar.so 
$ clang foo.c libbar.tramp.S libbar.init.c -o foo 
Các vấn đề liên quan