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

Использовать формы, объявленные в DLL

Delphi , Файловая система , DLL и PlugIns

Использовать формы, объявленные в DLL

Оформил: DeeCo
Автор: http://www.swissdelphicenter.ch

{ 
  In the example that follows the exe only sees a totally "virtual 
  abstract" interface to the object as is being exported from the dll 
  but it still can create the object and use it. 
  Of course the exe can not see or execute any methods declared in the 
  exe but that is the whole purpose of implementing them in a custom dll 
  to begin with. 

  Im folgenden Beispiel sieht die Exe-Datei nur ein total "virtuelles, abstraktes" 
  Interface zum Objekt, welches aus der Dll importiert wird aber es 
  kann doch dieses Objekt erzeugen und es gebrauchen. 
}


 // Example code: 

program Dlloader;

 uses
   Sharemem,
   Forms,
   exeunit1 in 'exeunit1.pas' {Form1},
   DllIntfu in 'DllIntfu.pas';

 {$R *.RES}

 begin
   Application.Initialize;
   Application.CreateForm(TForm1, Form1);
   Application.Run;
 end.

 //-------------------------- 

unit DllIntfu;

 interface

 type
   TDllobject = class
   protected
     function Get_UserName: string; virtual; abstract;
     procedure Set_UserName(Value: string); virtual; abstract;
   public
     property UserName: string read Get_UserName write Set_UserName;
   end;
   TDllobjectClass = class of TDllobject;

 implementation

 end.

 //--------------------------- 

unit exeunit1;

 interface

 uses
   Windows, Messages, SysUtils, Classes, Graphics,
   Controls, Forms, Dialogs, DllIntfu, StdCtrls;

 type
   TForm1 = class(TForm)
     Button1: TButton;
     procedure Button1Click(Sender: TObject);
   private
     { Private declarations }
   public
     { Public declarations }
   end;

 var
   Form1: TForm1;

 implementation

 {$R *.DFM}

 type
   TDllfunc = function: TDllobjectClass;
    stdcall;

 procedure TForm1.Button1Click(Sender: TObject);
 var
   i: DWORD;
   fHandle: THandle;
   fDllfunc: TDllfunc;
   fDllobject: TDllobject;
   fUserName: string;
 begin
   fHandle := LoadLibrary('UserName.dll');
   if (fHandle <> 0) then
   begin @fDllfunc := GetProcAddress(fHandle, 'Dllfunc');
     if Assigned(@fDllfunc) then
     begin
       i := 255;
       SetLength(fUserName, i);
       GetUserName(PChar(fUserName), i);
       fUserName           := StrPas(PChar(fUserName));
       fDllobject          := fDllfunc.Create;
       fDllobject.UserName := fUserName;
       ShowMessage(fDllobject.UserName);
       fDllobject.Free;
     end;
     FreeLibrary(fHandle);
   end;
 end;

 end.

 //------------------------------- 

library UserName;

 uses
   Sharemem,
   Sysutils,
   DllIntfu;

 type
   TCustomDllobject = class(TDllobject)
   private
     fUserName: string;
     function Getfilecount: Integer;
   protected
     function Get_UserName: string; override;
     procedure Set_UserName(Value: string); override;
   end;

   TCustomDllobjectclass = class of TCustomDllobject;

 function TCustomDllobject.Getfilecount: Integer;
 var
   doserr: Integer;
   fsrch: TSearchRec;
 begin
   Result := 0;
   doserr := FindFirst('*.*', faanyfile, fsrch);
   if (doserr = 0) then
   begin
     while (doserr = 0) do
     begin
       if (fsrch.attr and faDirectory) = 0 then
         Inc(Result);
       doserr := findnext(fsrch);
     end;
     FindClose(fsrch);
   end;
 end;

 function TCustomDllobject.Get_UserName: string;
 begin
   Result := 'You signed on as ''' + fUserName + '''' +
     ' and there ' + IntToStr(Getfilecount) +
     ' files in this directory.';
 end;

 procedure TCustomDllobject.Set_UserName(Value: string);
 begin
   fUserName := Value;
 end;

 function Dllfunc: TCustomDllobjectClass; stdcall;
 begin
   Result := TCustomDllobject; // class type only 
end;

 exports
   Dllfunc name 'Dllfunc';

 begin
 end.

Это пример использования форм, объявленных в DLL (динамической связанной библиотеке) из исполняемого файла Delphi.

DLL, называемый UserName.dll, содержит безформенный модуль, называемый DllIntfu, который объявляет абстрактный интерфейс для класса TDllobject. Интерфейс имеет два абстрактных метода: Get_UserName и Set_UserName, которые могут быть реализованы любым классом, наследующимся от TDllobject.

Исполняемый файл, называемый Dlloader.exe, использует модуль exeunit1.pas для создания экземпляра формы, называемой TForm1. Форма имеет кнопку, которая при клике загружает DLL с помощью LoadLibrary, получает указатель на функцию Dllfunc из DLL с помощью GetProcAddress и затем создает экземпляр TDllobject с помощью метода Create.

Класс TDllobject реализован в DLL как派生的 класс, называемый TCustomDllobject. Этот класс переопределяет абстрактные методы, объявленные в интерфейсе, и предоставляет свою собственную реализацию. Метод Get_UserName возвращает строку, содержащую имя пользователя, который вошел в систему, а также количество файлов в текущем каталоге.

Метод Set_UserName устанавливает свойство имени пользователя объекта. Функция Dllfunc используется для создания экземпляра TCustomDllobject и возврата его исполняющему файлу.

Вот некоторые предложения по улучшению кода:

  1. В модуле exeunit1.pas можно использовать оператор with для уменьшения количества строк кода:
procedure TForm1.Button1Click(Sender: TObject);
var
  i: DWORD;
  fHandle: THandle;
  fDllfunc: TDllfunc;
  fDllobject: TDllobject;
  fUserName: string;
begin
  with TForm1 do
  begin
    fHandle := LoadLibrary('UserName.dll');
    if (fHandle <> 0) then
    begin
      @fDllfunc := GetProcAddress(fHandle, 'Dllfunc');
      if Assigned(@fDllfunc) then
      begin
        // ...
      end;
    end;
  end;
end;
  1. В классе TCustomDllobject можно добавить более функциональность методу Getfilecount, используя рекурсивный поиск файлов в текущем каталоге.
  2. Можно использовать блок try-finally для обеспечения того, что DLL будет разгружен, когда он больше не нужен:
procedure TForm1.Button1Click(Sender: TObject);
var
  // ...
begin
  fHandle := LoadLibrary('UserName.dll');
  try
    @fDllfunc := GetProcAddress(fHandle, 'Dllfunc');
    if Assigned(@fDllfunc) then
    begin
      // ...
    end;
  finally
    FreeLibrary(fHandle);
  end;
end;
  1. Можно использовать раздел IMPLEMENTATION в DLL для отделения реализации от интерфейса.

В целом, этот код является хорошим примером использования форм, объявленных в DLL из исполняемого файла Delphi. Однако вам может потребоваться его рефакторинг для улучшения производительности и поддержки.

Использование форм, объявленных в DLL, позволяет создавать объекты и использовать их, не видя или выполнять методы, объявленные в исполняемом файле, что является целевым образом реализации методов в пользовательском DLL для начала.


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

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




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


:: Главная :: DLL и PlugIns ::


реклама


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

Время компиляции файла: 2024-12-22 20:14:06
2025-04-09 16:55:05/0.0056900978088379/1