Классы и длл
Как из динамически линкуемой длл загрузить класс? Гдето на глаза попадалась информация - не могу найти.
Если экспортируемый класс наследуется от TObject, можно просто создать функцию, экспортирующую ссылку на класс. Только в этом случае в обязательном порядке и для вызывающей программы, и для DLL придется использовать единую среду выполнения в виде пакетов.
Если экспортируемый класс наследуется от TObject, можно просто создать функцию, экспортирующую ссылку на класс. Только в этом случае в обязательном порядке и для вызывающей программы, и для DLL придется использовать единую среду выполнения в виде пакетов.
В длл реализовано несколько классов - некоторые наследуются от TObject - другие нет. Но когда я пытаюсь создать объект класса в вызывающей программе, постоянно возникает ошибка линкера -
Uresolved funtion TDocument::TDocument()... например. У классов унаследованыых от TObject проблем с вызовом конструктора не возникает - но если я в классе вызываю свою функцию - тоже самое. Как одно из решений гдето предлагалось экспортирование интерфейсов классов путем наследования от структуры. Чтото типа узкого ком объекта. Или возможно есть другой способ?
Вот как в данный момент это работает:
extern "C" TdmDoc* __declspec(dllexport)CreateDmModule(HWND CApp,char* server,char* user,char* pass,char* role);
//cpp-file
//Через функцию CreateDmModule создается объект
//класса TDataModule с перегруженным конструктором
//и указатель на него возвращается в вызвашее приложение
#include "rdocload.h"
#pragma argsused
TApplication *App;
HWND Handle;
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
if(reason==DLL_PROCESS_DETACH){
if(App)
Application = App;
}
return 1;
}
//---------------------------------------------------------------------------
TdmDoc* CreateDmModule(HWND CApp,char* server,char* user,char* pass,char* role)
{
if(!App){
App = Application;
Application->Handle = CApp;
}
TdmDoc *dmDoc;
return dmDoc = new TdmDoc(App,server,user,pass,role);
}
Все работает замечательно - но нет возможности слинковать модули приложения, например
....
typedef TdmDoc* (__import TDoc(HWND,char*,char*,char*,char*));
TDoc *Doc;
TdmDoc *dmDoc;
HINSTANCE dllInstance = LoadLibrary("dmregdoc.dll");
Doc = (TDoc*)GetProcAddress(dllInstance,"_CreateDmModule");
dmDoc = Doc(this,"server","user","pass","");
dmDoc->actConnect->Execute();
//До этого места все работает
dmDoc->LoadFromBase();//а вот здесь - ошибка линкера
Как одно из решений гдето предлагалось экспортирование интерфейсов классов путем наследования от структуры. Чтото типа узкого ком объекта. Или возможно есть другой способ?
Дело в том, что для экспорта класса надо все экспортируемые методы объявить как виртуальные. Тогда, соответственно, будет заголовочный файл с объявлением абстрактного класса, который будет использоваться и в DLL, и в приложении.
Дело в том, что для экспорта класса надо все экспортируемые методы объявить как виртуальные. Тогда, соответственно, будет заголовочный файл с объявлением абстрактного класса, который будет использоваться и в DLL, и в приложении.
т.е. абстрактный класс нужен обязательно и задействовать в объектах-наследниках я могу только те функции которые объявленны в данном классе?
т.е. абстрактный класс нужен обязательно и задействовать в объектах-наследниках я могу только те функции которые объявленны в данном классе?
Да. Есть также другой вариант - объявить методы как published (как объявляются обработчики событий VCL) и потом их находить по имени через RTTI.
Да. Есть также другой вариант - объявить методы как published (как объявляются обработчики событий VCL) и потом их находить по имени через RTTI.
Спасибо.
А можно подробней о RTTI? Как мне это реализовать?
Ведь само по себе объявление функции в published мало что даст. Как мне из другого приложения обратится к методу класса в длл используя RTTI?
Ведь само по себе объявление функции в published мало что даст.
Это даст автоматическую генерацию информации RTTI компилятором.
Все нужные функции для работы с RTTI описаны в модуле TypInfo.pas. Не знаю, документирован он в справке или нет, но по названиям функций там и так все понятно.
Задачу решил путем объявления функций классов виртуальными, а конструкторы классов экспортировал из длл - вроде решение не из самых плохих - заработало без проблем.
Задачу решил путем объявления функций классов виртуальными, а конструкторы классов экспортировал из длл - вроде решение не из самых плохих - заработало без проблем.
Не знаю, как на Билдере, а в Дельфи можно объявить виртуальный конструктор. Например, так создаются все потомки TComponent. Его наследников мы и экспортируем, как правило.
Не знаю, как на Билдере, а в Дельфи можно объявить виртуальный конструктор. Например, так создаются все потомки TComponent. Его наследников мы и экспортируем, как правило.
С виртуальными конструкторами я пок ане разобрался - оставил как есть. Реализую пока так как есть.