DLL浅析(2)
载入一个DLL有两种方法:隐式和显式(或称为:静态和动态)。其中静态载入又可以有两种方式:
1.定义接口单元,接口单元让DLL的调用者可以静态地引入DLL中的函数到应用程序中,应用程序只要在模块的uses子句中
包含引入单元名(如下面例子中的TestDLLInterface.pas)就可以使用这些函数。(其中Windows.pas就引入了kernel32.dll等DLL中的函数)。
unit TestDLLInterface
interface
type
function TestDLLFunc():word; StdCall;
implementation
fun TestDLLFunc; external 'TestDLL.dll' name 'TestDLLFunc';
end.
(同时使用接口单元的另一个好处是可以定义数据结构,使得DLL和应用程序都可以使用。)
2.在需要用到TestDLLFunc的pas单元的implementation中加入TestDLLFunc()的外部声明
function TestDLLFunc():word; StdCall;external 'TestDLL.dll';
当应用程序运行时,Win32系统自动载入TestDLL.dll,并且把dll映射到发起调用的应用程序进程空间。
动态载入DLL
interface
type
TTestDLLFunc = function():word; StdCall;
implement
function Test():word;
var
LibHandle: THandle;
TestDLLFunc:TTestDLLFunc;
begin
//LoadLibrary调用指定的DLL模块,把DLL映射到发起调用的过程地址空间中
LibHandle := LoadLibrary('TestDLL.dll');
try
if not (LibHandle = 0) then begin
@TestDLLFunc := GetProcAddress(LibHandle, 'TestDLLFunc');
if not(TestDLLFunc = nil) then
Result := TestDLLFunc();
end;
finally
1.定义接口单元,接口单元让DLL的调用者可以静态地引入DLL中的函数到应用程序中,应用程序只要在模块的uses子句中
包含引入单元名(如下面例子中的TestDLLInterface.pas)就可以使用这些函数。(其中Windows.pas就引入了kernel32.dll等DLL中的函数)。
unit TestDLLInterface
interface
type
function TestDLLFunc():word; StdCall;
implementation
fun TestDLLFunc; external 'TestDLL.dll' name 'TestDLLFunc';
end.
(同时使用接口单元的另一个好处是可以定义数据结构,使得DLL和应用程序都可以使用。)
2.在需要用到TestDLLFunc的pas单元的implementation中加入TestDLLFunc()的外部声明
function TestDLLFunc():word; StdCall;external 'TestDLL.dll';
当应用程序运行时,Win32系统自动载入TestDLL.dll,并且把dll映射到发起调用的应用程序进程空间。
动态载入DLL
interface
type
TTestDLLFunc = function():word; StdCall;
implement
function Test():word;
var
LibHandle: THandle;
TestDLLFunc:TTestDLLFunc;
begin
//LoadLibrary调用指定的DLL模块,把DLL映射到发起调用的过程地址空间中
LibHandle := LoadLibrary('TestDLL.dll');
try
if not (LibHandle = 0) then begin
@TestDLLFunc := GetProcAddress(LibHandle, 'TestDLLFunc');
if not(TestDLLFunc = nil) then
Result := TestDLLFunc();
end;
finally
//FreeLibrary通过减少LibModule指定的DLL实例数量,如果实例数量为零就从内存中删除这个库。实例计数保持着当前使用DLL的任务数量。
FreeLibrary();
end;
end;
浙公网安备 33010602011771号