2013-02-19 3 views
7

Tôi muốn viết một số mã C (okay nếu nó chỉ hoạt động trên Linux) để tự động tải một thư viện được chia sẻ mới, và sau đó gọi một phương thức từ nó (được xác định khi chạy). Có vẻ như điều này đã có thể bởi vì java có thể tải các thư viện tự động, và sau đó gọi các phương thức từ chúng.Làm cách nào để tải thư viện của riêng mình theo cách động và gọi phương thức trong thư viện?

Ví dụ, tôi muốn làm một cái gì đó như:

int main() { 
    libinfo_t * lib_details = load_shared_library("libfoo.so"); 
    run_method(lib_details, "bar", 7); 
} 

này sẽ gọi phương thức 'bar' với lập luận 7 (bar là một phương pháp biên dịch vào libfoo.so).

Sử dụng trường hợp chi tiết:

Tôi muốn biên dịch một nhị phân tải tất cả các thư viện chia sẻ trong một thư mục, và chạy một số phương pháp từ mỗi, trong bối cảnh bộ nhớ của chương trình gốc. Tôi muốn có thể nhanh chóng bật hoặc tắt thư viện được chia sẻ bằng cách thêm/xóa thư viện đó khỏi thư mục.

Bằng chứng về khái niệm:

Dường như này nên có thể, dựa trên cách java quản lý để liên kết với mã JNI động. Bạn có thể sử dụng System.load() và tải thư viện bạn chọn. Cùng với việc biên dịch từ bộ nhớ, có vẻ như nó sẽ cho phép bạn chạy một hàm tùy ý từ một thư viện tùy ý. http://www.java2s.com/Code/Java/JDK-6/CompilingfromMemory.htm

Những điều tôi đã cố gắng:

  1. Tôi đã nhìn manpage cho 'uselib', mà dường như có ích, nhưng tôi không biết phải làm gì với thư viện một lần tôi đã nạp nó.

  2. Một chút googling trả lại http://dyncall.org/, nhưng điều này không chính xác những gì tôi cần - dự án này vẫn yêu cầu một con trỏ hàm để thực hiện cuộc gọi hàm.

Tôi rất biết ơn bất kỳ con trỏ nào về vị trí tiếp theo, ngay cả khi không có câu trả lời cụ thể. Cảm ơn!

+0

C không có phương thức nhưng chức năng. –

Trả lời

9

Linux có API hoàn chỉnh cho việc này. Đó là API dlopen(3).

Trước tiên, bạn gọi dlopen với một tên tập tin để có được một tay cầm thư viện chia sẻ:

void* lib = dlopen("./lib.so"); 

Thân, để có được một con trỏ hàm cho một hàm trong thư viện này:

int (*func)() = dlsym(lib, "thing"); 

Sử dụng con trỏ này như bạn vui lòng.

Cuối cùng, khi bạn đã hoàn tất:

dlclose(lib) 

Lưu ý: Hãy nhớ để làm kiểm tra lỗi!

+1

Rất tiếc, cảm ơn bạn đã trả lời nhanh! Âm thanh chính xác như những gì tôi đang tìm kiếm. – jstrom

+1

@jstrom: Chắc chắn rồi! Vui mừng được giúp đỡ. Nhân tiện, chào mừng bạn đến với SO! Câu hỏi hay. Hy vọng bạn quay trở lại! Nó cũng giống như bạn đọc các câu hỏi thường gặp - yay! :). – Linuxios

+2

Bạn có thể muốn đặt một '/' trong đường dẫn, ví dụ: 'dlopen (" ./ lib.vì vậy ");' nếu không 'LD_LIBRARY_PATH' hoặc nội dung tương đương của nó được sử dụng. –