![]() |
|
|
Регистрация | << Правила форума >> | 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; То есть интерфейс освобождается автоматически. |
#7
|
|||
|
|||
![]() Попробуйте переопределить функции _Addref и _Release в Вашем объекте и поставьте в них трассировку.
|
#8
|
|||
|
|||
![]() Цитата:
В каком именно объекте ? Последний раз редактировалось evgeso, 16.02.2011 в 16:02. |