![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
|
|
#1
|
|||
|
|||
|
Доброго времени суток
Для начала приведу исходный код потом буду задавать вопрос Код:
TPluginManager = class(TInterfaceList,IPluginManager);
...
function TPluginManager.LoadLib(const FileName:String;var Handle:THandle) : boolean;
var
LibHandle:THandle;
begin
LibHandle := LoadLibrary(PChar(FileName));
if LibHandle = 0 then Result:=False
else
Result:=RegLib(LibHandle,FileName);
Debug('[TPluginManager.RegLib] Библиотека ['+FileName+'] загружена');
end;Для теста корректности написал функцию выгрузки, которая по нажатию на кнопку должна была выгружать библиотеки(Интерфейсы библиотек ни кем не используются.) Выгружаю приблизительно так : Код:
procedure TPluginManager.UnloadAllLibs;
var
Index:Integer;
HWD:THandle;
begin
Debug('[TPluginManager.UnloadAllLibs] Выгружаем библиотеки');
HWD:=ISimplePlugin(Items[0]).GetHandle;
Delete(0);
if FreeLibrary(HWD) then ShowMessage('Вігрузили')
else ShowMessage('Ошибка');
end;Элемент ноль подставлен для тестирования а вообще выгрузка идет в цикле. Запускаю выгрузку с формы на нажатию кнопки: Код:
procedure TMainAppForm.Button2Click(Sender: TObject);
var
V:IPluginManager;
begin
ShowMessage('=====');
V:=FEngine.GetPluginManger; // Возвращает IPluginManager(TPluginManager)
V.UnloadAllLibs;
ShowMessage('----');
end;В результате После нажатия кнопки я получаю (после всех ShowMessage и записей в журнал) Access Violation. Delphi указывает на строку выделенную жирным шрифтом в последнем листинге. При том что функция UnloadAllLibs полностью выполняется (проверено дебаг сообщениями стоящими после begin и перед end); Такое впечатление что когда делается FreeLibrary(HWD) приложение не знает адрес возврата из функции Вообщем вопрос прост что за хрен или как ровнять руки ? PS : Не знал куда отнести свой вопрос,потому написал в эту ветку. Писал на Pascal,Delphi,C,C++,ASM но не профессионально потому считаю себя новичком ![]() Последний раз редактировалось evgeso, 11.02.2011 в 17:43. |
|
#2
|
|||
|
|||
|
Не понимаю тут что я один ?
|
|
#3
|
|||
|
|||
|
Давай код RegLib,в остальном коде на первый взгляд все нормально.
Очень похоже, что где-то выделяется память и не отдается. |
|
#4
|
|||
|
|||
|
Код:
function TPluginManager.GetPluginInterface(Handle: THandle): ISimplePlugin;
var
Func:function : TInterfacedObject;
Obj:TObject;
Info:ISimplePlugin;
begin
DebugLog('[TPluginManager.GetPluginInterface] Поиск функции GetPluginInf');
@Func:=GetProcAddress(Handle,'GetPluginInf');
if @Func<>nil then
begin
Obj:=Func;
DebugLog('[TPluginManager.GetPluginInterface] Функция GetPluginInf нацдена');
if not TInterfacedObject(Obj).GetInterface(ISimplePlugin,Result) then
begin
DebugLog('[TPluginManager.GetPluginInterface] Результат не вернул интерфейс.');
Result:=nil
end
else
DebugLog('[TPluginManager.GetPluginInterface] Результат вернул интерфейс.');
@Func := nil;
end
else
begin
DebugLog('[TPluginManager.GetPluginInterface] Функция GetPluginInf не найдена.');
Result:=nil;
end;
end;
function TPluginManager.RegLib(Handle: THandle;
FileName: WideString): boolean;
var
LibInterface:ISimplePlugin;
Index:Integer;
begin
DebugLog('[TPluginManager.RegLib] Регистрируем библиотеку['+FileName+']');
LibInterface:=GetPluginInterface(Handle);
if LibInterface=nil then
begin
Result:=False;
WarningMsg('[TPluginManager.RegLib] Интерфейс не найден');
Exit;
end;
if VerifyInf(LibInterface) then
try
LibInterface.SetHandle(Handle);
LibInterface.SetPluginFileName(FileName);
Add(LibInterface);
DebugLog('[TPluginManager.RegLib] Зарегестрирована');
Result:=True;
except
Result:=False;
end
end;
|
|
#5
|
|||
|
|||
|
Ну, так по коду криминала не видно.
Попробуй при удалении сначала освободить интерфейс, а потом уже удалять. Впечатление, что проходит вызов к уже выгруженной библиотеке. |
|
#6
|
|||
|
|||
|
Цитата:
В Исходнике TInterfaceList Код:
procedure TInterfaceList.Delete(Index: Integer);
begin
with FList.LockList do
try
Self.Put(Index, nil);
Delete(Index);
finally
Self.FList.UnlockList;
end;
end;То есть интерфейс освобождается автоматически. |