Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Освобождение библиотеки DLL после получения интерфейса: решение проблемы доступа в памяти

Delphi , Программа и Интерфейс , Интерфейс

Рассмотрим проблему, связанную с освобождением динамически подключаемой библиотеки (DLL), которая возвращает интерфейс для класса, находящегося внутри библиотеки. При использовании явной загрузки DLL все происходит успешно, но при попытке освободить библиотеку возникает ошибка доступа к памяти (Access Violation). Это происходит, несмотря на то, что если просто загрузить библиотеку и сразу же освободить ее без получения интерфейса, то ошибок не возникает.

Контекст проблемы

Вопрос пользователя заключается в следующем: имеется DLL, содержащая класс, реализующий интерфейс. DLL имеет экспортируемый метод, который возвращает этот интерфейс. При использовании явной загрузки DLL все проходит без ошибок, но при вызове функции освобождения библиотеки возникает Access Violation. Автор вопроса не пробовал использовать неявную ссылку, так как ему необходимо использовать именно явный режим работы.

Структура DLL

В DLL определен интерфейс ITefFacade, который содержит функцию IniciarTransacao. Класс TTefFacade наследуется от TInterfacedObject и реализует интерфейс ITefFacade. В DLL также присутствует функция CreateTef, которая создает экземпляр TTefFacade и возвращает интерфейс для этого объекта.

Пример кода DLL

library Tef;
uses
  uTTefFacade;
{$R *.res}
exports
  CreateTef;
begin
end.

type
  ITefFacade = interface
  ['{77691DD1-C6E9-4F75-951F-BFA1468DC36C}']
    function IniciarTransacao(AParam: TTefIniciarTransacaoParamDTO): TTefIniciarTransacaoResultDTO;
  end;

type
  TTefFacade = class(TInterfacedObject, ITefFacade)
  private
    function IniciarTransacao(AParam: TTefIniciarTransacaoParamDTO): TTefIniciarTransacaoResultDTO;
  public
    constructor Create;
    destructor Destroy; override;
  end;

function CreateTef: ITefFacade; export; stdcall;
function CreateTef: ITefFacade;
begin
  Result := ITefFacade(TTefFacade.Create);
end;

Пример использования DLL в exe-приложении

Пример использования DLL в приложении на Delphi показывает, что после загрузки DLL и получения интерфейса, при освобождении библиотеки происходит Access Violation.

procedure TForm1.FormCreate(Sender: TObject);
var
  CreateTef: function: ITefFacade; stdcall;
begin
  try
    FTef := nil;
    FHTef := LoadLibrary('Tef.dll');
    if (FHTef > 0) then
    begin
      @CreateTef := GetProcAddress(FHTef, 'CreateTef');
      if (@CreateTef <> nil) then
        FTef := CreateTef;
    end;
    if (FTef = nil) then
      ShowMessage('Error.');
  except
    on E: Exception do
      ShowMessage('Erro: ' + E.Message);
  end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FreeLibrary(FHTef);
end;

Подтвержденный ответ

Проблема, с которой столкнулся пользователь, заключается в неправильном управлении ресурсами интерфейса. Для корректного освобождения библиотеки необходимо сначала освободить интерфейс, полученный из DLL, и только после этого можно освобождать саму библиотеку.

Комментарии и альтернативный ответ

В комментариях пользователи обсуждают важность освобождения интерфейса перед освобождением библиотеки. Один из пользователей отметил, что присвоение nil переменной FTef перед освобождением библиотеки помогло решить проблему. Также было отмечено, что необходимо изучить различия между классами и интерфейсами, и что в классе TTefFacade следует использовать destructor Destroy; override; вместо destructor Free;.

Рекомендации

  1. Перед освобождением библиотеки убедитесь, что все интерфейсы, полученные из нее, были освобождены.
  2. Используйте FreeAndNil для безопасного освобождения объектов.
  3. В классе TTefFacade следует использовать destructor Destroy; вместо destructor Free;, так как TInterfacedObject управляет подсчетом ссылок.

Пример использования FreeAndNil

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FreeAndNil(FTef);
  FreeLibrary(FHTef);
end;

Используя этот подход, вы избежите ошибок доступа в памяти при освобождении библиотеки, которая содержит интерфейсы для классов.

Создано по материалам из источника по ссылке.

Проблема заключается в необходимости корректного освобождения интерфейса, полученного из динамически подключаемой библиотеки (DLL), перед освобождением самой библиотеки, чтобы избежать ошибок доступа к памяти.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Интерфейс ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-02-05 14:39:48/0.0057199001312256/1