Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 11.02.2011, 17:24
evgeso evgeso вне форума
Прохожий
 
Регистрация: 11.02.2011
Сообщения: 6
Репутация: 10
По умолчанию При выгрузке библиотеки Access Violation

Доброго времени суток
Для начала приведу исходный код потом буду задавать вопрос
Код:
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;
RegLib добавляет интерфейс в список и заполняет ещё пару свойств интерфейсов.
Для теста корректности написал функцию выгрузки, которая по нажатию на кнопку должна была выгружать библиотеки(Интерфейсы библиотек ни кем не используются.)
Выгружаю приблизительно так :
Код:
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  
Старый 13.02.2011, 05:27
evgeso evgeso вне форума
Прохожий
 
Регистрация: 11.02.2011
Сообщения: 6
Репутация: 10
По умолчанию

Не понимаю тут что я один ?
Ответить с цитированием
  #3  
Старый 13.02.2011, 06:18
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,096
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Давай код RegLib,в остальном коде на первый взгляд все нормально.
Очень похоже, что где-то выделяется память и не отдается.
Ответить с цитированием
  #4  
Старый 13.02.2011, 18:56
evgeso evgeso вне форума
Прохожий
 
Регистрация: 11.02.2011
Сообщения: 6
Репутация: 10
По умолчанию

Код:
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  
Старый 13.02.2011, 20:15
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,096
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Ну, так по коду криминала не видно.
Попробуй при удалении сначала освободить интерфейс, а потом уже удалять. Впечатление, что проходит вызов к уже выгруженной библиотеке.
Ответить с цитированием
  #6  
Старый 13.02.2011, 20:41
evgeso evgeso вне форума
Прохожий
 
Регистрация: 11.02.2011
Сообщения: 6
Репутация: 10
По умолчанию

Цитата:
Сообщение от lmikle
Попробуй при удалении сначала освободить интерфейс, а потом уже удалять.
Что вы имеете в виду ?
В Исходнике 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  
Старый 14.02.2011, 12:54
icWasya icWasya вне форума
Местный
 
Регистрация: 09.11.2010
Сообщения: 499
Репутация: 10
По умолчанию

Попробуйте переопределить функции _Addref и _Release в Вашем объекте и поставьте в них трассировку.
Ответить с цитированием
  #8  
Старый 16.02.2011, 15:57
evgeso evgeso вне форума
Прохожий
 
Регистрация: 11.02.2011
Сообщения: 6
Репутация: 10
По умолчанию

Цитата:
Сообщение от icWasya
Попробуйте переопределить функции _Addref и _Release в Вашем объекте и поставьте в них трассировку.

В каком именно объекте ?

Последний раз редактировалось evgeso, 16.02.2011 в 16:02.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 07:53.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025