Difference between revisions of "DLL dynamically load/zh CN"

From Lazarus wiki
Jump to navigationJump to search
(Created page with "{{DLL_dynamically_load |DLL_动态地_加载}} 这篇教程向你展示如何动态地加载一个DLL(动态链接库)。 The DLL (DLLTest.dll) referred to in the example be...")
 
 
(3 intermediate revisions by the same user not shown)
Line 3: Line 3:
 
这篇教程向你展示如何动态地加载一个DLL(动态链接库)。
 
这篇教程向你展示如何动态地加载一个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 32: Line 32:
 
我应该做什么:
 
我应该做什么:
  
* 定义存储器
+
* 定义存储器内存
** A data type must be created that corresponds exactly to the (external) subroutine that is to be imported from the DLL.
+
** 必需创建一个数据类型,这个数据类型必需与从DLL文件中所导入的(external)子程序的数据类型相一致。
 
* 保留存储器
 
* 保留存储器
** 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.
+
** 必需为一个处理程序/句柄(handle)预留存储器内存, DLL文件中的处理程序/句柄(handle)稍后将分配。
* Assign DLL and external subroutine and accept the data
+
* 分配DLL和外部的子例程并接受数据
** Call the DLL and assign the handle of the DLL to the handle.
+
** 调用DLL文件,并将DLL文件中的处理程序/句柄(handle)分配到处理程序/句柄(handle)。
** The pointer for the variables must be changed to the memory of the external subroutine.
+
** 变量的指针必需更改为external子程序的存储器内存。
** The result of the external subroutine is to be accepted.
+
** external子程序的结果可以被接受。
* Free all memory
+
* 释放所有的存储器
** The pointer for the variables must point to an invalid memory area again (:= nil) to release the external subroutine.
+
** 变量的指针必须再次指向一个无效的存储器区域(:= nil)以释放外部的子程序。
** The memory of the DLL must be released again.
+
** DLL的存储器必须再次释放。
  
Integrate, use and release the DLL subroutine in your own program:
+
在你自己的程序中,集成/融入、使用和释放DLL中的子程序:
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 55: Line 55:
 
  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);
Line 88: Line 88:
 
   ...
 
   ...
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 +
= 贡献者和更改 =
 +
* 简体中文版本由 [[User:Robsean | robsean]] 于 2021-10-19 创建(2021-11-04完成全部翻译)。

Latest revision as of 13:58, 4 November 2021

Windows logo - 2012.svg

This article applies to Windows only.

See also: 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文件中所导入的(external)子程序的数据类型相一致。
  • 保留存储器
    • 必需为上面的数据类型分配一个变量(数据字段),并预留存储器内存。
    • 必需为一个处理程序/句柄(handle)预留存储器内存, DLL文件中的处理程序/句柄(handle)稍后将分配。
  • 分配DLL和外部的子例程并接受数据
    • 调用DLL文件,并将DLL文件中的处理程序/句柄(handle)分配到处理程序/句柄(handle)。
    • 变量的指针必需更改为external子程序的存储器内存。
    • external子程序的结果可以被接受。
  • 释放所有的存储器
    • 变量的指针必须再次指向一个无效的存储器区域(:= 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;

   ...

贡献者和更改

  • 简体中文版本由 robsean 于 2021-10-19 创建(2021-11-04完成全部翻译)。