2011-01-12 44 views
8

Do một số hạn chế, tôi bị buộc phải tải thư viện được viết bằng C khi chạy. Bên thứ ba cung cấp hai thư viện cho tôi dưới dạng lưu trữ tĩnh mà chúng tôi chuyển thành các đối tượng được chia sẻ. Ứng dụng tôi đang làm việc với tải một trong các thư viện trong thời gian chạy dựa trên một số tham số phần cứng. Thật không may một trong những thư viện được cấu hình chủ yếu với các biến toàn cầu.dlopen và biến toàn cầu trong C/C++

Tôi đã sử dụng dlsym để tải các tham chiếu hàm nhưng tôi có thể sử dụng dlsym để tải các tham chiếu đến các biến toàn cục này không?

Trả lời

10

Có, bạn có thể sử dụng dlsym để truy cập các hình cầu (miễn là chúng được xuất và không tĩnh). Ví dụ dưới đây là trong C + + và Mac, nhưng rõ ràng C sẽ hoạt động tốt.

lib.cpp:

extern "C" { 
    int barleyCorn = 12; 
} 

uselib.cpp

#include <dlfcn.h> 
#include <iostream> 
using namespace std; 

main() 
{ 
    void * f = dlopen ("lib.dylib", RTLD_NOW); 
    void * obj = dlsym (f, "barleyCorn"); 
    int * ptr = (int *) obj; 
    cout << *ptr << endl; 
} 

Output:

% ./a.out 
12 
+0

Và ngay cả khi bạn tải thư viện C++ từ thời gian chạy C, tất cả đối tượng chung của bạn sẽ được tạo! Và bị phá hủy khi bạn dỡ nó – yanpas

1

Có, bạn có thể định vị bất kỳ biểu tượng đã xuất nào trong thư viện động sử dụng dlsym().

1

Có bạn có thể và tôi thực sự thích làm điều này hơn là tải các chức năng. Mô hình IOC tiêu chuẩn của tôi thực hiện theo cách đó.

tôi thích nó vì:

  • Dàn diễn viên từ một void * đến một con trỏ đến một đối tượng là kỹ thuật an toàn hơn mà để một con trỏ hàm, mặc dù rõ ràng là hệ thống có sử dụng void * với dlsym phải cho phép bạn chuyển đổi con trỏ. (GetProcAddress của Microsoft trả về kiểu con trỏ của riêng chúng, trong trường hợp này tôi nghĩ là một lựa chọn tốt hơn vì chúng có thể thay đổi ý nghĩa thực sự của điều này sau này nếu chúng cần). Bởi vì tôi làm điều đó trong C + +, tôi có thể thực thi rằng bất kỳ đối tượng được xuất khẩu nào xuất phát từ một lớp cơ sở chung, và sau đó tôi có thể sử dụng dynamic_cast từ lớp đó đến lớp thực tế mà tôi mong đợi. Điều này có nghĩa là tôi có thể gặp lỗi nếu nó không xuất phát từ lớp sau, tiết kiệm lỗi thời gian chạy sau này.

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