2009-07-17 24 views
15

Tôi có một đối tượng được chia sẻ (tương tự như vậy - tương đương với Linux của một dll Windows) mà tôi muốn nhập và sử dụng với mã thử nghiệm của mình.Làm cách nào để tải một đối tượng được chia sẻ trong C++?

tôi chắc chắn rằng nó không phải đơn giản này;) nhưng đây là loại điều tôi muốn làm ..

#include "headerforClassFromBlah.h" 

int main() 
{ 
    load("blah.so"); 

    ClassFromBlah a; 
    a.DoSomething(); 
} 

tôi cho rằng đây là một câu hỏi thực sự cơ bản nhưng tôi không thể tìm thấy bất cứ thứ gì nhảy ra ngoài tìm kiếm trên web.

+0

Có thể bạn đã nhầm lẫn nhưng không giống như bạn có đủ thông tin ở đó. Ví dụ, blah.so chứa gì? Bạn chắc chắn bạn không chỉ nói về việc sử dụng một tài liệu tham khảo? – Goz

+0

Bạn có ý nghĩa gì khi "chia sẻ" chính xác? – Klaim

+0

Err ... vì vậy tệp không phải là tệp mã, phải không? Có thể bạn muốn lấy một đối tượng từ a.tệp (thư viện được chia sẻ) như vậy? – Klaim

Trả lời

33

Có hai cách để tải chia sẻ đối tượng trong C++

Đối với một trong các phương pháp này bạn sẽ luôn luôn cần các tập tin tiêu đề cho đối tượng bạn muốn sử dụng. Tiêu đề sẽ chứa các định nghĩa của các lớp hoặc các đối tượng bạn muốn sử dụng trong mã của bạn.

Tĩnh:

#include "blah.h" 
int main() 
{ 
    ClassFromBlah a; 
    a.DoSomething(); 
} 

gcc yourfile.cpp -lblah 

động (Trong Linux):

#include <stdio.h> 
#include <stdlib.h> 
#include <dlfcn.h> 
int main(int argc, char **argv) { 
    void *handle; 
    double (*cosine)(double); 
    char *error; 
    handle = dlopen ("libm.so", RTLD_LAZY); 
    if (!handle) { 
     fprintf (stderr, "%s\n", dlerror()); 
     exit(1); 
    } 
    dlerror(); /* Clear any existing error */ 
    cosine = dlsym(handle, "cos"); 
    if ((error = dlerror()) != NULL) { 
     fprintf (stderr, "%s\n", error); 
     exit(1); 
    } 
    printf ("%f\n", (*cosine)(2.0)); 
    dlclose(handle); 
    return 0; 
} 

* bị đánh cắp từ dlopen Linux man page Quá trình này dưới cửa sổ hay bất kỳ nền tảng khác là như nhau, chỉ cần thay thế dlopen với các phiên bản nền tảng tìm kiếm biểu tượng động.

Để phương thức động hoạt động, tất cả các ký hiệu bạn muốn nhập/xuất phải có liên kết C bên ngoài.

Có một số từ Here về thời điểm sử dụng tĩnh và thời điểm sử dụng liên kết động.

+5

+1. Có lẽ giá trị một đề cập rõ ràng rằng dlopen là POSIX, không phải C hoặc C++. Trên một số nền tảng không có tải động nhưng chúng vẫn phù hợp với việc triển khai C++. –

+0

Lệnh để xây dựng tệp này là gì, g ++ filename.cpp -L someIncludes -0 có hoạt động không? –

+0

Bạn sẽ cần phải liên kết bằng cách sử dụng -ldl quá –

4

Tùy thuộc vào nền tảng. Để làm điều đó trong thời gian chạy, trên Linux, bạn sử dụng dlopen, trên cửa sổ, bạn sử dụng LoadLibrary.

Để làm điều đó tại thời gian biên dịch, trên cửa sổ bạn xuất tên hàm sử dụng dllexportdllimport. Trên Linux, gcc xuất tất cả các biểu tượng công khai để bạn chỉ có thể liên kết với nó bình thường và gọi hàm. Trong cả hai trường hợp, thông thường điều này yêu cầu bạn phải có tên của biểu tượng trong một tệp tiêu đề mà bạn sau đó #include, sau đó bạn liên kết đến thư viện bằng cách sử dụng các phương tiện của trình biên dịch của bạn.

3

Bạn cần # bao gồm bất kỳ tiêu đề nào được liên kết với thư viện được chia sẻ để nhận các tuyên bố về những thứ như ClassFromBlah. Sau đó bạn cần phải liên kết chống lại các .so - chính xác như thế nào bạn làm điều này phụ thuộc vào trình biên dịch của bạn và instalation chung, nhưng đối với g ++ gì đó như:

g++ myfile.cpp -lblah 

lẽ sẽ làm việc.

+0

Tôi đã bao gồm các tiêu đề và tôi có thể biên dịch và liên kết mã của tôi với đối tượng được chia sẻ nhưng tôi không biết cách sử dụng nó và các lớp chứa nó - Tôi không làm rõ điều đó, xem cập nhật của tôi cho đoạn mã. Bất kỳ ý tưởng nào? –

+1

Về cách sử dụng các lớp chứa trong đó, bạn phải RTFM, tôi sợ. –

+0

@neil Đó có lẽ là giải pháp mà Ben cần ... Câu trả lời được chấp nhận dlopen có thể chỉ là một giải thích sai về câu hỏi mới bắt đầu (Ben?) ... @Ben L: Nếu bạn không biết có gì trong đó. vì vậy bạn sẽ gặp vấn đề khi sử dụng nó với dlsym ;-) – neuro

0

Đó là -l liên kết tệp lưu trữ như libblah.a hoặc nếu bạn thêm -PIC vào gcc, bạn sẽ nhận được tệp 'đối tượng chia sẻ' libblah.so (đó là trình liên kết xây dựng nó). Tôi đã có mặt trời một lần và đã xây dựng các loại tệp này. Các tệp có thể có số sửa đổi phải chính xác hoặc cao hơn (Mã có thể đã thay đổi do lỗi). nhưng cuộc gọi có tham số phải giống với đầu ra.

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