Я пытаюсь создать DLL, которая содержит модуль данных VCL — идея заключается в том, что различные приложения могут загружать одну и ту же DLL и использовать один и тот же код базы данных.
Сам модуль данных протестирован нормально как часть приложения — я скопировал форму в свой проект DLL.
Итак, в методе точки входа dll мне нужно инициализировать модуль данных:
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
//if I don't call this, I get an exception on initializing the data module
CoInitialize(NULL);
//initialize a standard VCL form; seems to works fine
//I'm not using Application->CreateForm as I don't want the form to appear straight away
if(!MyForm) MyForm = new TMyForm(Application);
//this doesn't work - the thread seems to hang in the TDataModule base constructor?
//I've also tried Application->CreateForm; same result
if(!MyDataModule) MyDataModule = new TMyDataModule(Application);
}
Я также видел кое-что о том, как мне нужно вызвать Application-> Initialize перед созданием формы, но, похоже, это не имеет значения.
Есть идеи?
Спасибо
Вы действительно не должны делать очень много работы в вашем DllEntryPoint()
совсем. Конечно, не звонит CoInitialize()
, тем не мение. DLL не несет ответственности за вызов этого при загрузке. Это ответственность вызывающего приложения перед загрузкой DLL.
Вы должны либо:
экспортировать дополнительную функцию, чтобы инициализировать вашу DLL и затем загрузить ее после загрузки DLL (то же самое для удаления DLL перед ее выгрузкой)
не создавайте свой модуль TForm / TDataModule до тех пор, пока DLL не понадобится в первый раз.
переместите ваш TForm / TDataModule в их собственный рабочий поток внутри DLL. В этом случае вы бы тогда позвонили CoIniitalize()
,
И ни в коем случае не передавайте DLL Application
Объект для управления временем жизни вашего TForm / TDataModule. Освободите их сами перед тем, как DLL будет выгружена.
Других решений пока нет …