2009-10-04 25 views

Trả lời

3

Trả lời câu hỏi của bạn đúng, bạn cần phải thêm một extern "C" hàm trả về kết quả của các nhà xây dựng:

extern "C" foo* __declspec(dllexport) new_foo(int x) { 
    return new foo(x); 
} 

Sau đó, trong nguồn của bạn, bạn có thể sử dụng GetProcAddr vào "new_foo" để gọi hàm .

3

Bạn sẽ cần xuất một hàm từ DLL gọi đến hàm khởi tạo và trả về đối tượng mới.

Cố gắng tránh sử dụng các loại C++ cụ thể làm thông số chức năng; ý tưởng của các tệp DLL là bạn có thể cập nhật chúng một cách độc lập, nhưng trình biên dịch được nâng cấp có thể đặt ra std :: string khác nhau, gây ra sự không tương thích khi chạy.

Đây là nội dung gốc của COM, ví dụ - hệ thống loại giới hạn và chức năng được xuất chuẩn để nhận các phiên bản của đối tượng.

+0

Tt âm thanh như thể nguồn DLL không nằm trong tầm kiểm soát của anh ta. –

+0

Nguồn DLL nằm dưới sự kiểm soát của tôi – SomeUser

+0

Nếu lớp được dự định sẽ được sử dụng, thì có lẽ nó đã được biên dịch với __declspec (dllexport), do đó, nó chỉ là vấn đề thuyết phục tệp tiêu đề để đặt __declspec (dllimport) trong định nghĩa lớp. Nếu không, bạn luôn có thể tự sửa đổi tập tin tiêu đề. – JesperE

10

Bạn cần khai báo lớp học của mình bằng cách sử dụng từ khóa __declspec(dllexport) khi tạo DLL. Khi sử dụng các DLL, lớp cần phải được khai báo với __declspec(dllimport):

#ifdef COMPILING_DLL 
#define DECLSPEC_CLASS __declspec(dllexport) 
#else 
#define DECLSPEC_CLASS __declspec(dllimport) 
#endif 

class DECLSPEC_CLASS MyClass 
{ 
... 
} 

Khi DLL được biên dịch, bạn nên thêm -DCOMPILING_DLL vào danh sách các định nghĩa.

Khi sử dụng lớp, bạn phải liên kết tĩnh với DLL, tức là chuyển thư viện nhập mydll.lib vào chương trình chính.

Nếu bạn muốn tải DLL khi chạy, bạn cần có hàm C trong DLL tạo đối tượng và trả về cho bạn. Không có cách nào để tra cứu một constructor động trong một DLL (sử dụng GetProcAddress()).

+1

Bạn có thể trích dẫn nguồn cho câu lệnh cuối cùng không? AFAIK một ctor có một tên bị cắt xén, và bạn có thể gọi GetProcAddress bằng cách sử dụng tên đó. Điều gì sẽ ngăn cản bạn? – MSalters

+0

Vâng, về mặt kỹ thuật, bạn đã đúng. Giao diện – JesperE

3

Thay vì xuất khẩu tất cả các phương thức của lớp sử dụng __declspec, bạn cũng có thể dựa trên thực tế là trình biên dịch có thể gọi chức năng ảo qua vtable, vì vậy ví dụ:

//note: no __declspec 
class IPublicInterface 
{ 
    virtual ~IPublicInterface() = 0; 
    virtual void SomeMethod() = 0; 
}; 

//note: no __declspec 
class SomeClass : IPublicInterface 
{ 
    virtual ~SomeClass() { ... } 
    virtual void SomeMethod() { ... } 
}; 

//note: this is the only method which needs to be exported from the DLL 
IPublicInterface* createSomeClass() 
{ 
    return new SomeClass(); 
} 
+0

/nhà máy rất đẹp, đặc biệt nếu bạn định sử dụng 'GetProcAddress' và bảng được xuất thủ công .def xuất khẩu –

+0

Vì bộ nhớ được cấp phát trong DLL, có lẽ cũng nên có' freeSomClass (IPublicInterface *) ' đảm bảo bộ nhớ được giải phóng chính xác? – Robert

+0

Tôi nghĩ câu trả lời này là sai và nên bị xóa. Bạn không thể chuyển đối tượng đa hình qua ranh giới của plugin, ngoại trừ khi trình biên dịch chính xác được sử dụng trong cả plugin và ứng dụng. –

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