Làm thế nào để tạo một số lớp từ dll (constructor in dll)? (С ++) hoặc cách tự động tải lớp từ dll?Làm thế nào để tạo một số lớp từ dll (constructor in dll)? (С ++)
Trả lời
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 .
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.
Tt âm thanh như thể nguồn DLL không nằm trong tầm kiểm soát của anh ta. –
Nguồn DLL nằm dưới sự kiểm soát của tôi – SomeUser
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
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()).
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();
}
/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 –
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
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. –
bạn có một tập tin tiêu đề phù hợp và/hoặc tập tin thư viện để truy cập vào dll? –
vâng tôi có tiêu đề và nguồn của tôi – SomeUser