Difference between revisions of "DLL dynamically load/zh CN"
From Free Pascal wiki
Jump to navigationJump to search(One intermediate revision by the same user not shown) | |||
Line 15: | Line 15: | ||
{$R *.res} | {$R *.res} | ||
− | // | + | // DLL文件中的子程序 |
function funStringBack(strIn : string) : PChar; | function funStringBack(strIn : string) : PChar; | ||
begin | begin | ||
Line 32: | Line 32: | ||
我应该做什么: | 我应该做什么: | ||
− | * | + | * 定义存储器内存 |
− | ** | + | ** 必需创建一个数据类型,这个数据类型必需与从DLL文件中所导入的(external)子程序的数据类型相一致。 |
* 保留存储器 | * 保留存储器 | ||
− | ** | + | ** 必需为上面的数据类型分配一个变量(数据字段),并预留存储器内存。 |
− | ** | + | ** 必需为一个处理程序/句柄(handle)预留存储器内存, DLL文件中的处理程序/句柄(handle)稍后将分配。 |
* 分配DLL和外部的子例程并接受数据 | * 分配DLL和外部的子例程并接受数据 | ||
− | ** | + | ** 调用DLL文件,并将DLL文件中的处理程序/句柄(handle)分配到处理程序/句柄(handle)。 |
− | ** | + | ** 变量的指针必需更改为external子程序的存储器内存。 |
− | ** | + | ** external子程序的结果可以被接受。 |
* 释放所有的存储器 | * 释放所有的存储器 | ||
** 变量的指针必须再次指向一个无效的存储器区域(:= nil)以释放外部的子程序。 | ** 变量的指针必须再次指向一个无效的存储器区域(:= nil)以释放外部的子程序。 | ||
Line 61: | Line 61: | ||
// 为DLL子程序创建一个合适的变量(数据字段) | // 为DLL子程序创建一个合适的变量(数据字段) | ||
funStringBack : TfunStringBack; | funStringBack : TfunStringBack; | ||
− | // | + | // 为DLL创建一个处理程序/句柄 |
LibHandle : THandle; | LibHandle : THandle; | ||
begin | begin | ||
− | // | + | // 获取将要使用的库的处理程序/句柄 |
LibHandle := LoadLibrary(PChar('DLLTest.dll')); | LibHandle := LoadLibrary(PChar('DLLTest.dll')); | ||
− | // | + | // 检查是否成功加载DLL文件 |
if LibHandle <> 0 then | if LibHandle <> 0 then | ||
begin | begin | ||
Line 75: | Line 75: | ||
Pointer(funStringBack) := GetProcAddress(LibHandle, 'funStringBack'); | Pointer(funStringBack) := GetProcAddress(LibHandle, 'funStringBack'); | ||
− | // | + | // 检查是否已经返回一个有限的存储器内存地址 |
if @funStringBack <> nil then | if @funStringBack <> nil then | ||
Result := funStringBack('hello world'); | Result := funStringBack('hello world'); | ||
end; | end; | ||
− | // | + | // 释放存储器内存 |
funStringBack := nil; | funStringBack := nil; | ||
FreeLibrary(LibHandle); | FreeLibrary(LibHandle); | ||
Line 90: | Line 90: | ||
= 贡献者和更改 = | = 贡献者和更改 = | ||
− | * 简体中文版本由 [[User:Robsean | robsean]] 于 2021-10-19 创建(2021- | + | * 简体中文版本由 [[User:Robsean | robsean]] 于 2021-10-19 创建(2021-11-04完成全部翻译)。 |
Latest revision as of 13:58, 4 November 2021
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完成全部翻译)。