Форум: "Основная";
Текущий архив: 2003.10.09;
Скачать: [xml.tar.bz2];
ВнизFreeLibrary... need Help! Найти похожие ветки
← →
MetalFan (2003-09-26 09:31) [0]доброе время суток, мастера!
проблема такая:
есть проект, в котором используются н-ко похожих (в плане експортируемых функций) DLL.
в цикле грузятся по очереди все ДЛЛки (их около 10), вызывается одна функция, затем ДЛЛ выгружается.
при выгрузке одной из DLL вылетает Acces Violation at adress XXXXXXX.
остальные ДЛЛ загружаются и выгружаются нормально!
вот код загрузки/выгрузки:
procedure LoadListDll;
var
F: TSearchRec;
Info: TInfoTest;
GetPlayerInfo: function: TInfoTest;
Lib: THandle;
APath:String;
function FindTest(TestVid: Integer): Boolean;
var
i: Integer;
begin
Result:=False;
for i:=0 to High(DllList)-1 do
begin
Result:=(DllList[i].TestVid=TestVid);
if Result then Exit;
end;
end;
begin
if FindFirst(ExtractFilePath(Application.ExeName)+"players_dll\*.dll", faAnyFile, F)<>0 then Exit;
repeat
APath:=ExtractFilePath(Application.ExeName)+"players_dll\"+F.Name;
try
Lib:=LoadLibrary(PChar(APath));
except
ShowMessage("error load dll");
end;
if (Lib<>0) then
begin
@GetPlayerInfo:=GetProcAddress(Lib, "GetPlayerInfo");
//на ДЛЛ с этим именем валится Acces Vioaltion
if f.Name="testobj2area_v1_p.dll" then begin
showmessage("try to unload");
///здесь!!!!!!!!!
FreeLibrary(Lib);
showmessage("Unloaded!");
continue
end;
if Assigned(GetPlayerInfo) then
begin
Info:=GetPlayerInfo;
if FindTest(Info.TestVid) then begin FreeLibrary(Lib); ShowMessage("cont");Continue; end;
SetLength(DllList, Length(DllList)+1);
DllList[High(DllList)].DLLpath:=APath;
DllList[High(DllList)].TestVid:=Info.TestVid;
DllList[High(DllList)].Name:=Info.TestName;
DllList[High(DllList)].Instance:=0;
try
FreeLibrary(Lib);
except
ShowMessage("error Unload dll 1");
end;
end
else
try
FreeLibrary(Lib);
except
ShowMessage("error Unload dll 2");
end;
end;
until FindNext(F)<>0;
FindClose(F);
end;
← →
MetalFan (2003-09-26 09:34) [1]ах да! DLLList описан так:
var
DllList: array of record
TestVid : Integer;
Name : String;
DLLpath : String;
Instance: THandle;
Window : THandle;
Init : procedure(AApplication, Parent: THandle;const file: String; Func: PFunctions; var Window: THandle);
Term : procedure;
Execute : procedure;
SetData : procedure(DataStream: TStream);
GetResult : function(DataStream: TStream):boolean;
end;
← →
Digitman (2003-09-26 09:35) [2]и что же ты хотел ?
откуда нам знать, что у тебя там в этой DLL творится)
← →
MetalFan (2003-09-26 09:38) [3]функция GetPlayerInfo в ДЛЛ описана так:
library MyDLL1;
....
type
TInfoTest = record
TestVid: Integer;
TestName : ShortString;
end;
....
function GetPlayerInfo: TInfoTest;export;
begin
Result.TestVid:=15;
Result.TestName:="Название";
end;
....
exports
GetPlayerInfo
← →
MetalFan (2003-09-26 09:39) [4]до Freelibrary кроме вызова этой функции ниче с ДЛЛ больше не делаю!
← →
Digitman (2003-09-26 09:45) [5]1. ShareMem используется ? В Dll и хост-приложении ?
2. Какие-то процедуры финализации реализованы в этой DLL ?
← →
MetalFan (2003-09-26 09:48) [6]1. в ДЛЛ да, а в хост надо?
2. никакие
← →
Palladin (2003-09-26 09:50) [7]надо, читай внимательней то что пишут
← →
MetalFan (2003-09-26 09:56) [8]сделал... все-равно сыпеся.
еще замечу - попробовал так:
создал "с нуля" приложение, кинул кнопу на форму и под нее загружаю, вызываю GetPlayerInfo и выгружаю ДЛЛ. все нормально, информация приходит.
а в большом проекте, где много всего, эта ДЛЛ работать-раболтает, а при выгрузке Acces Violation дает(((
← →
Digitman (2003-09-26 10:01) [9]склонен предположить к тому же, что состояние опции Build with Run-Time packages для проекта данной DLL отличается от других DLL-проектов
← →
Digitman (2003-09-26 10:03) [10]
> а при выгрузке Acces Violation дает
и ты даже не удосужился ни поинтересоваться деталями этого исключения ни привести их здесь ... ведь кроме собственно фразы "Acces Violation" сообщение об исключении дает массу ценной инф-ции для поиска источника/причин проблемы !!!
← →
MetalFan (2003-09-26 10:05) [11]не отличается! не стоит опция не в одной длл(((
← →
MetalFan (2003-09-26 10:10) [12]
> Digitman ©
Инструкция по адресу "0х025b3912" обратилась к памяти по адресу "0x02fc3050". Память не может быть "read"
....
← →
Digitman (2003-09-26 10:16) [13]для начала ищи по FindHInstance() , какому модулю процесса принадлежит данный (0х025b3912) адрес
← →
MetalFan (2003-09-26 10:20) [14]а что это даст?
← →
Verg (2003-09-26 10:21) [15]Скажи
вот это я вижу,
SetLength(DllList, Length(DllList)+1);
А где инициализация DllList?
← →
Digitman (2003-09-26 10:26) [16]
> MetalFan
это даст инф-цию о том, при исполнения кода в каком конкретном модуле происходит нарушение доступа по чтению
← →
Digitman (2003-09-26 10:44) [17]library MyDLL1;
....
type
PInfoTest = ^TInfoTest;
TInfoTest = packed record
TestVid: Integer;
TestName : ShortString;
end;
....
function GetPlayerInfo(InfoTest: PInfoTest): Boolean;
begin
with InfoTest^ do
begin
TestVid:=15;
TestName:="Название";
end;
Result := True;
end;
....
exports
GetPlayerInfo;
-----------------------------------------------------------
type
TGetPlayerInfo = function(InfoTest: PInfoTest): Boolean;
...
procedure LoadListDll;
var
F: TSearchRec;
Info: TInfoTest;
GetPlayerInfo: TGetPlayerInfo;
Lib: THandle;
APath:String;
function FindTest(TestVid: Integer): Boolean;
var
i: Integer;
begin
Result:=False;
for i:=0 to High(DllList)-1 do
begin
Result:=(DllList[i].TestVid=TestVid);
if Result then Exit;
end;
end;
begin
if FindFirst(ExtractFilePath(Application.ExeName)+"players_dll\*.dll", faAnyFile, F)<>0 then Exit;
repeat
APath:=ExtractFilePath(Application.ExeName)+"players_dll\"+F.Name;
Lib:=LoadLibrary(PChar(APath));
if Lib = 0 then
begin
ShowMessage(SysErrorMessage(GetLastError));
Continue;
end;
try
GetPlayerInfo:=GetProcAddress(Lib, "GetPlayerInfo");
if Assigned(GetPlayerInfo) then
try
if GetPlayerInfo(@Info)and not FindTest(Info.TestVid) then
begin
SetLength(DllList, Length(DllList)+1);
DllList[High(DllList)].DLLpath:=APath;
DllList[High(DllList)].TestVid:=Info.TestVid;
DllList[High(DllList)].Name:=Info.TestName;
DllList[High(DllList)].Instance:=0;
end;
except
on e: Exception do
ShowMessage("Error :" + e.ClassName + ", Msg: " + e.Message);
end
finally
FreeLibrary(Lib);
end;
until FindNext(F)<>0;
FindClose(F);
end;
← →
Verg (2003-09-26 11:02) [18]
> function GetPlayerInfo(InfoTest: PInfoTest): Boolean;
А смысл?
Если функция струтурного типа, то вызывающая процедура просто отводит место в стеке для результата и передает адрес на это место в вызываемую.
Ты сделал по сути то же самое, просто явно указал адрес куда нужно результат класть
← →
Digitman (2003-09-26 11:16) [19]
> Verg
А завтра автору захочется еще полей понавтыкать в эту структуру ?)
Уже при данной структуре в стеке резервируется 260 байт, а что будет, если он еще косой десяток ShortString"ов ?)
Он же не понимает этого, по всей видимости !
Ни к чему совершенно такой подход !
← →
Verg (2003-09-26 11:30) [20]
> Digitman © (26.09.03 11:16) [19]
Все верно.
Просто происхождение AV это не объясняет.
Вообще, если все именно так, как рассказывает автор, то есть подозрение, что это опять же не глюк в DLL, а порча памяти где-то в другом месте приложения. Просто именно эта DLL попадает "под раздачу", может из-своего относительного положения в памяти в силу, скажем, постояноной очередности загрузки (FindFirst/next всегда ж в одном и том же порядке отдает список).
← →
MetalFan (2003-09-26 13:19) [21]
> Verg ©
нет, если оставить не 10, а 3, то валится на той же единственной.
← →
Verg (2003-09-26 14:16) [22]
> нет, если оставить не 10, а 3, то валится на той же единственной.
Если честно, то я в чудеса не верю. Ошибка есть, просто она сейчас вообще вне поля зрения.
Весь исходник посмотреть/погонять возможности нет.
Локализовать проблему ты тоже не можешь.
А, как говориться, "на ведьм охотиться" - дело неблагодарное.
← →
MetalFan (2003-09-26 17:48) [23]всем спасибо за советы!!!
тему считаю закрытой, решение траблы отложено... ))
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2003.10.09;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.009 c