Проблема с загрузкой DLL
Может кто сталкивался подскажите в чем может быть проблема.
Суть в следующем:
Есть основная программа, которая загружает формы из длл. Программа простая как липисин - форма, меню, и фукция клика по разделу меню.
Функция выглядит примерно так:
Все что не определено в фукции - определяются снаружи.
Dlls имеет тип TStringList и заполняется при помощи FindFirst, FindNext...
{
AnsiString dllName,menuName = ((TMenuItem*)Sender)->Name;
typedef AnsiString (__import *Prop)();
typedef HWND (__import *Sh)(AnsiString &Capt);
Prop MyProp;
Sh ShowMy;
HINSTANCE Dll;
for (int i = 0; i < Dlls->Count; i++)
{
Dll = LoadLibrary(Dlls->Strings.c_str());
if (Dll != NULL)
{
MyProp = (Prop)GetProcAddress (Dll,"_ReturnProperty");
dllName = MyProp();
}
if(menuName != dllName)
{
FreeLibrary(Dll);
}
else
{
ShowMy = (Sh)GetProcAddress(Dll,"_ShowDllForm");
AnsiString B = ((TMenuItem*)Sender)->Caption;
ShowMy(B);
break;
}
}
}
Каждая ДЛЛ содержит файл dllfunc10.cpp, к примеру, в котором описаны и объявлены экспортируемые функции.
Примерно так:
//--dllfunc10.h
#ifndef dllfunc10H
#define dllfunc10H
AnsiString Name = "miFirmAddres";
extern "C" __declspec(dllexport) AnsiString ReturnProperty();
extern "C" __declspec(dllexport) HWND ShowDllForm(AnsiString &Capt);
//---------------------------------------------------------------------------
#endif
//--dllfunc10.cpp
#include <vcl.h>
#pragma hdrstop
#include "dllfunc10.h"
#include "dllform10_1.h"
AnsiString ReturnProperty()
{
return Name;
}
HWND ShowDllForm(AnsiString &Capt)
{
TForm1 *f = new TForm1(Application);
f->Caption = Capt;
f->Show();
return f->Handle;
}
Теперь собственно, проблема. Таких ДЛЛ в проекте штук десять. Все компилируются и линкуются с одинаковыми параметрами. По отдельности все работает превосходно...:(
Когда собираю все в кучу - получаю Access violetion по адресу... в модуле основной программы.
Ошибка возникает в различных модулях:
>dllName = MyProp();
Когда указатель на функцию МyProp() возращает значение и оно присваеваится dllName!
Иногда удается загрузится без ошибки. При проходе дебагером все функции и значения инициализируются и имеют нормальные значения.
Зарание благодарю.
Теперь собственно, проблема. Таких ДЛЛ в проекте штук десять. Все компилируются и линкуются с одинаковыми параметрами. По отдельности все работает превосходно...:(
Когда собираю все в кучу - получаю Access violetion по адресу... в модуле основной программы.
Ошибка возникает в различных модулях:
Когда указатель на функцию МyProp() возращает значение и оно присваеваится dllName!
Иногда удается загрузится без ошибки. При проходе дебагером все функции и значения инициализируются и имеют нормальные значения.
Зарание благодарю.
Эх, приятно всеже увидеть свой код, даже имена функций не изменены, вот так и становятся классиками=)Теперь о проблеме.У меня в проекте таких dll уже за 150. Проблем никаких не возникает, проект изначально был в BCB5 теперь в BCB6. Все линкуется с использованием Runtime Packeges&Dynamic RTL. Теперь, что значит собираю все в кучу?Ты чтоли все dll засунул в один проект?Каждая dll должна быть в своем проекте.Хост в своем проекте.
Эх, приятно всеже увидеть свой код, даже имена функций не изменены, вот так и становятся классиками=)
Классиками - когда серебряной покрасят И пива нальют...:)
Теперь, что значит собираю все в кучу?Ты чтоли все dll засунул в один проект?Каждая dll должна быть в своем проекте.Хост в своем проекте.
Бр...что значит в своем проекте? Я имею ввиду уже готовую программу. Есть отдельный проект хоста, для каждой дельки свой проект, но когда я собираю енто(я имею ввиду ехе и длл) в рабочую дир, получаю ошибку...:( Сегодня - завтра сделаю полную ревизию, может где ошибку допустил...но даже не представляю где искать.
dllnewpr.dll
dlloutvc.dll
dllost.dll
...
и т.п.
Если я сразу после старта загружаю dllost.dll (к примеру) - получаю ошибку.
Если dllnewpr.dll - все фурычит.
Не въеду, в чем глюк.
Ошибка возникает, когда не загружена первая длл, т.е. есть список:
dllnewpr.dll
dlloutvc.dll
dllost.dll
...
и т.п.
Если я сразу после старта загружаю dllost.dll (к примеру) - получаю ошибку.
Если dllnewpr.dll - все фурычит.
Не въеду, в чем глюк.
Хотел бы заметить, что наш "классик" пишет неаккуратный код. Смотрим
if(Dll != NULL)
{
MyProp = (Prop)GetProcAddress(Dll,"_ReturnProperty");
dllName = MyProp();
}
if(menuName != dllName)
{
FreeLibrary(Dll);
}
Еслии DLL не загрузилась (Dll=0), мы не будем получать адрес метода "_ReturnProperty" и dllName, а сразу сравним dllName (?) с menuName, потом еще и освободим незагруженную DLL.
Может проблема в этом?
Хотел бы заметить, что наш "классик" пишет неаккуратный код. Смотрим
if(Dll != NULL)
{
MyProp = (Prop)GetProcAddress(Dll,"_ReturnProperty");
dllName = MyProp();
}
if(menuName != dllName)
{
FreeLibrary(Dll);
}
Еслии DLL не загрузилась (Dll=0), мы не будем получать адрес метода "_ReturnProperty" и dllName, а сразу сравним dllName (?) с menuName, потом еще и освободим незагруженную DLL.
Может проблема в этом?
Прошу прощения, но здесь ошибка не moonmike а, ваша. В первом if определяется загружена ли длл, и только после, во втором сравниваются стороки...Может я скобочку забыл. А проблема не в этом.
//--dllfunc10.h
#ifndef dllfunc10H
#define dllfunc10H
AnsiString Name = "miFirmAddres";
extern "C" __declspec(dllexport) AnsiString ReturnProperty();
extern "C" __declspec(dllexport) HWND ShowDllForm(AnsiString &Capt);
//---------------------------------------------------------------------------
#endif
Может тебе стоит попробовать
вместо:
AnsiString Name = "miFirmAddres";
поставить:
const char *Name = "miFirmAddres"; ?
Просто не исключен вариант некорректной отработки самой AnsiString - с подобной проблемой я столкнулся недавно - два разных объекта TStringList - в один добавляешь строку, в другом данные тут-же почему-то исчезают... Романтика!!!
Может тебе стоит попробовать
вместо:
AnsiString Name = "miFirmAddres";
поставить:
const char *Name = "miFirmAddres"; ?
Просто не исключен вариант некорректной отработки самой AnsiString - с подобной проблемой я столкнулся недавно - два разных объекта TStringList - в один добавляешь строку, в другом данные тут-же почему-то исчезают... Романтика!!!
Сложно сказть, мелкософт вообще не рекомендует передавать из динамической дельки данные отличные от типа const char* :)), в связи с возможностью некорректного освобождения памяти, но проблема я думаю все же не в этом, перерыл все проекты, заново их отстроил, заново перекомпилил хост - проблема исчезла.
Думаю что причиной была где-то пропущенная опция линковщика.
Если ошибка находилась в самом классе строк, была бы проблема с загрузкой всех длл, а так после загрузки превой все работало в штатном режиме...;/