Difference between revisions of "DLL dynamically load/ru"

From Free Pascal wiki
Jump to navigationJump to search
(Created page with "{{DLL_dynamically_load}} The tutorial shows how a DLL (Dynamic Link Library) is loaded dynamically . The DLL (DLLTest.dll) referred to in the example below: <syntaxhighligh...")
 
 
Line 1: Line 1:
 
{{DLL_dynamically_load}}
 
{{DLL_dynamically_load}}
  
The tutorial shows how a DLL (Dynamic Link Library) is loaded dynamically .
+
В руководстве показано, как динамически загружается DLL (библиотека динамической компоновки).  
  
The DLL (DLLTest.dll) referred to in the example below:
+
Библиотека DLL (DLLTest.dll), указанная в примере ниже:
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 15: Line 15:
 
  {$R *.res}
 
  {$R *.res}
  
  // The DLL subroutine
+
  // Подпрограмма DLL
 
  function funStringBack(strIn : string) : PChar;
 
  function funStringBack(strIn : string) : PChar;
 
   begin
 
   begin
Line 22: Line 22:
  
  
  // Exported subroutine(s)
+
  // Экспортированная подпрограмма(ы)
 
  exports
 
  exports
 
   funStringBack;
 
   funStringBack;
Line 30: Line 30:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
What should I do:
+
Что я должен делать:
 +
* Определить память
 +
** Необходимо создать тип данных, который точно соответствует (внешней) подпрограмме, которая должна быть импортирована из DLL.
 +
* Зарезервировать память
 +
** Память должна быть зарезервирована для переменной (поля данных), которой назначен указанный выше тип данных.
 +
** Память должна быть зарезервирована для дескриптора, которому дескриптор DLL будет назначен позже.
 +
* Назначить DLL и внешнюю подпрограмму и принимаемые данные
 +
** Вызвать DLL и назначить дескриптору DLL дескриптор.
 +
** Указатель переменных должен быть заменен на память внешней подпрограммы.
 +
** Результат внешней подпрограммы должен быть принят.
 +
* Освободить всю память
 +
** Указатель на переменные должен снова указывать на недопустимую область памяти (:= nil), чтобы освободить внешнюю подпрограмму.
 +
** Память DLL необходимо снова освободить.
  
* Define memory
+
Интегрируйте, используйте и выпустите подпрограмму DLL в вашей собственной программе:
** A data type must be created that corresponds exactly to the (external) subroutine that is to be imported from the DLL.
 
* Reserve memory
 
** Memory must be reserved for a variable (data field) to which the above data type is assigned.
 
** Memory must be reserved for a handle, to which the DLL handle will be assigned later.
 
* Assign DLL and external subroutine and accept the data
 
** Call the DLL and assign the handle of the DLL to the handle.
 
** The pointer for the variables must be changed to the memory of the external subroutine.
 
** The result of the external subroutine is to be accepted.
 
* Free all memory
 
** The pointer for the variables must point to an invalid memory area again (:= nil) to release the external subroutine.
 
** The memory of the DLL must be released again.
 
 
 
Integrate, use and release the DLL subroutine in your own program:
 
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 55: Line 54:
 
  Include function funDll : string;
 
  Include function funDll : string;
 
  type
 
  type
   // Definition of the subroutine to be called, as defined in the DLL to be used
+
   // Определение вызываемой подпрограммы, как задано в DLL, которая будет использоваться
 
   TfunStringBack = function(strIn : string) : PChar;  stdcall;
 
   TfunStringBack = function(strIn : string) : PChar;  stdcall;
  
 
  var
 
  var
   // Creates a suitable variable (data field) for the DLL subroutine
+
   // Создаем подходящую переменную (поле данных) для подпрограммы DLL
 
   funStringBack : TfunStringBack;
 
   funStringBack : TfunStringBack;
   // Creates a handle for the DLL
+
   // Создаем дескриптор для DLL
 
   LibHandle : THandle;
 
   LibHandle : THandle;
  
 
  begin
 
  begin
   // Get the handle of the library to be used
+
   // Получаем дескриптор библиотеки, которая будет использоваться
 
   LibHandle := LoadLibrary(PChar('DLLTest.dll'));
 
   LibHandle := LoadLibrary(PChar('DLLTest.dll'));
  
   // Checks whether loading the DLL was successful
+
   // Проверяем успешность загрузки DLL
 
   if LibHandle <> 0 then
 
   if LibHandle <> 0 then
 
     begin
 
     begin
       // Assigns the address of the subroutine call to the variable funStringBack
+
       // Назначаем адрес вызова подпрограммы переменной funStringBack
       // 'funStringBack' from the DLL DLLTest.dll
+
       // 'funStringBack' из DLL DLLTest.dll
 
       Pointer(funStringBack) := GetProcAddress(LibHandle, 'funStringBack');
 
       Pointer(funStringBack) := GetProcAddress(LibHandle, 'funStringBack');
  
       // Checks whether a valid address has been returned
+
       // Проверяет, был ли возвращен действительный адрес
 
       if @funStringBack <> nil then
 
       if @funStringBack <> nil then
 
         Result := funStringBack('hello world');
 
         Result := funStringBack('hello world');
 
     end;
 
     end;
  
   // release memory
+
   // освобождаем память
 
   funStringBack := nil;
 
   funStringBack := nil;
 
   FreeLibrary(LibHandle);
 
   FreeLibrary(LibHandle);

Latest revision as of 18:31, 15 December 2020

Windows logo - 2012.svg

Эта статья относится только к Windows.

См. также: Multiplatform Programming Guide

Deutsch (de) English (en) русский (ru) 中文(中国大陆)‎ (zh_CN)

В руководстве показано, как динамически загружается DLL (библиотека динамической компоновки).

Библиотека DLL (DLLTest.dll), указанная в примере ниже:

 library info;

 {$mode objfpc} {$H+}

 uses
   SysUtils;

 {$R *.res}

 // Подпрограмма DLL
 function funStringBack(strIn : string) : PChar;
   begin
     funStringBack := PChar(UpperCase(strIn));
   end ;


 // Экспортированная подпрограмма(ы)
 exports
   funStringBack;

 begin
 end.

Что я должен делать:

  • Определить память
    • Необходимо создать тип данных, который точно соответствует (внешней) подпрограмме, которая должна быть импортирована из DLL.
  • Зарезервировать память
    • Память должна быть зарезервирована для переменной (поля данных), которой назначен указанный выше тип данных.
    • Память должна быть зарезервирована для дескриптора, которому дескриптор DLL будет назначен позже.
  • Назначить DLL и внешнюю подпрограмму и принимаемые данные
    • Вызвать DLL и назначить дескриптору DLL дескриптор.
    • Указатель переменных должен быть заменен на память внешней подпрограммы.
    • Результат внешней подпрограммы должен быть принят.
  • Освободить всю память
    • Указатель на переменные должен снова указывать на недопустимую область памяти (:= nil), чтобы освободить внешнюю подпрограмму.
    • Память DLL необходимо снова освободить.

Интегрируйте, используйте и выпустите подпрограмму DLL в вашей собственной программе:

 uses
   Windows, ...;

   ...

 Include function funDll : string;
 type
   // Определение вызываемой подпрограммы, как задано в DLL, которая будет использоваться
   TfunStringBack = function(strIn : string) : PChar;  stdcall;

 var
   // Создаем подходящую переменную (поле данных) для подпрограммы DLL
   funStringBack : TfunStringBack;
   // Создаем дескриптор для DLL
   LibHandle : THandle;

 begin
   // Получаем дескриптор библиотеки, которая будет использоваться
   LibHandle := LoadLibrary(PChar('DLLTest.dll'));

   // Проверяем успешность загрузки DLL
   if LibHandle <> 0 then
     begin
       // Назначаем адрес вызова подпрограммы переменной funStringBack
       // 'funStringBack' из DLL DLLTest.dll
       Pointer(funStringBack) := GetProcAddress(LibHandle, 'funStringBack');

       // Проверяет, был ли возвращен действительный адрес
       if @funStringBack <> nil then
         Result := funStringBack('hello world');
     end;

   // освобождаем память
   funStringBack := nil;
   FreeLibrary(LibHandle);

 end;

   ...