2011-09-13 34 views
7

Tôi đang sử dụng các công cụ GNU nhất định, ví dụ: Trình biên dịch GNU C++ (g ++) và Trình liên kết GNU (ld) để tạo tệp thư viện (.so) được chia sẻ cũng như một tệp thực thi nhị phân.Vấn đề nhận trình liên kết GNU (ld) để xuất biểu tượng

Tệp thi hành nhị phân giúp sử dụng hàm dlopen để tự động tải tệp thư viện được chia sẻ khi chạy. Ngoài ra, tệp thư viện được chia sẻ cần gọi một phương thức lớp cụ thể (được gọi là ToolboxManager::registerToolbox) được xác định trong tệp thực thi nhị phân. Điều này được cung cấp bằng cách buộc thực thi nhị phân để xuất phương thức lớp, do đó được thực hiện tại thời gian liên kết bằng cách liên kết tệp thực thi nhị phân với các tùy chọn dòng lệnh sau;

-Wl,--dynamic-list=${top_srcdir}/dynamic_symbol_table.txt 

nơi tệp ${top_srcdir}/dynamic_symbol_table.txt chứa nội dung sau;

{ 
    extern "C++" 
    { 
    "ToolboxManager::registerToolbox*"; 
    }; 
}; 

Lưu ý việc sử dụng dấu hoa thị (*) trong tập tin để buộc các mối liên kết để xuất khẩu tất cả các biểu tượng mà bắt đầu với ToolboxManager::registerToolbox.

Khi tôi chạy tiện ích GNU nm (nm -C -g ./a.out) trên kết quả thực thi nhị phân, nó sẽ hiển thị thông tin sau về phương pháp lớp được đề cập ở trên;

08053da0 T ToolboxManager::registerToolbox 
      ( 
      std::string&, 
      std::string&, 
      std::map 
      < 
      std::string, 
      Factory_DSPB_Base*, 
      std::less 
      < 
       std::string 
      >, 
      std::allocator 
      < 
       std::pair 
       < 
       std::string const, 
       Factory_DSPB_Base* 
       > 
      > 
      >& 
      ) 

hoặc, nếu tiện ích nm được gọi như trên, nhưng lần này mà không sử dụng công tắc dòng lệnh -C;

08053da0 T _ZN14ToolboxManager15registerToolboxERSsS0_RSt3mapISsP17Factory_DSPB_BaseSt4lessISsESaISt4pairIKSsS3_EEE 

Cho đến nay, điều này có vẻ ổn. Chữ "T" ở phía trước định nghĩa của phương thức lớp ToolboxManager::registerToolbox, biểu thị rằng phương thức nằm trong phần Văn bản/Mã của tệp.

Tương tự, nếu tôi chạy tiện ích nm (nm -C -g ./toolbox.so) trên tệp thư viện được chia sẻ, nó sẽ hiển thị thông tin sau về cùng phương thức tương tự;

U ToolboxManager::registerToolbox 
    (
    std::string&, 
    std::string&, 
    std::map 
    < 
    std::string, 
    Factory_DSPB_Base*, 
    std::less 
    < 
    std::string 
    >, 
    std::allocator 
    < 
    std::pair 
    < 
     std::string const, 
     Factory_DSPB_Base* 
    > 
    > 
    >& 
) 

Điều này cũng ổn. Chữ "U" phía trước định nghĩa của phương thức lớp ToolboxManager::registerToolbox, biểu thị rằng phương thức này không được xác định trong tệp thư viện được chia sẻ.

Tuy nhiên, sự cố xảy ra khi tôi chạy tệp nhị phân có thể thoát khỏi dòng lệnh và sự cố này dẫn đến thông báo lỗi sau được hiển thị;

./toolbox.so: undefined symbol: _ZN14ToolboxManager15registerToolboxERSsS0_RSt3mapISsP17Factory_DSPB_BaseSt4lessISsESaISt4pairIKSsS3_EEE 

Tên phương thức phân lớp xuất hiện trong thông báo thời gian chạy này được hiển thị bên dưới, làm đầu tiên trong hai dòng. Đối với mục đích so sánh, tên phương thức lớp bị xáo trộn từ phía trên (và được tạo ra bằng cách sử dụng lệnh nm -g) được hiển thị bên dưới là phần thứ hai của hai dòng;

_ZN14ToolboxManager15registerToolboxERSsS0_RSt3mapISsP17Factory_DSPB_BaseSt4lessISsESaISt4pairIKSsS3_EEE 

_ZN14ToolboxManager15registerToolboxERSsS0_RSt3mapISsP17Factory_DSPB_BaseSt4lessISsESaISt4pairIKSsS3_EEE 

Có thể thấy, hai tên bị xáo trộn giống nhau. Vì vậy, tôi không thể hiểu tại sao biểu tượng không xác định không thể được giải quyết trong thời gian chạy.

Sau đó tôi liên kết lại tệp thực thi nhị phân, tuy nhiên lúc này tôi đã thay thế lệnh trình liên kết sau;

-Wl,--dynamic-list=${top_srcdir}/dynamic_symbol_table.txt 

bằng cái này;

-Wl,--export-dynamic 

Tùy chọn trình liên kết --export-dynamic chỉ thị cho Trình liên kết GNU thêm tất cả ký hiệu vào bảng ký hiệu động.

Nếu sau đó chạy lại tệp nhị phân. Lần này nó thực thi chính xác và cuộc gọi đến chức năng dlopen không dẫn đến lỗi biểu tượng không xác định. Điều này làm tôi bối rối hoàn toàn, vì có vẻ như biểu tượng đang được xuất chính xác trong phiên bản đầu tiên của tệp thực thi nhị phân. Có ai có thể thấy vấn đề ở đây không? Bất kỳ hỗ trợ nào sẽ được đánh giá cao.

Xin cảm ơn trước.

Trả lời

3

Tôi đã cố gắng giải quyết vấn đề này. Tôi đã tìm thấy rằng nếu tôi loại bỏ các dấu ngoặc kép từ dòng sau;

"ToolboxManager::registerToolbox*" 

trong tệp ${top_srcdir}/dynamic_symbol_table.txt và sau đó liên kết lại tệp nhị phân, sau đó hoạt động. Đó là, chức năng dlopen sẽ không thất bại nữa.

Tôi không thể không tự hỏi liệu có thích hợp hơn khi hỏi câu hỏi này trên danh sách gửi thư của binutils GNU hơn ở đây trên trang web này không.

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