当前位置:首页 > Windows程序 > 正文

Delphi中DLL的其他应用

2021-03-29 Windows程序

1.DLL的入口函数和出口函数

在编写DLL时可以在DLL项目文件的begin..end之间加入DLL的进入口函数和出口函数,全局变量DLLProc是一个过程指针,指定入口/出口函数,初始值为nil,只需将自己的出入口函数赋值给它即可,自己的出入口函数必须传入一个DWord类型的参数。一下是出入口函数事件对应的用途。

DLL_PROCESS_ATTACH 在进程启动或调用LoadLibrary( )时,DLL映射到当前进程的地址空间。在这个事件期间,D L L初始化实例数据
DLL_PROCESS_DETACH DLL正从进程的地址空间分离出来,这也许是进程本身退出或调用了FreeLibrary( )。在该事件里,D L L也许没有初始化任何实例。
DLL_THREAD_ATTACH 进程创建了一个新线程。这时,系统会调用所有和这个进程相关联的DLL入口函数。这个调用在新线程的环境中进行,用于分配线程特定的数据
DLL_THREAD_DETACH 一个线程正在退出。在该事件里,DLL将释放线程特定的初始化数据
警告 调用TerminateThread()非正常终止线程时,没有调用DLL_THREAD_DETACH。

2.DLL中使用回调函数

回调函数一般被Win32DLL或其他DLL调用,而不是由应用程序调用。当调用回调函数时传递函数的地址。在DLL可以定义一种回调函数类型,然后将其做为导出函数的参数,实际应用程序调用DLL时需自己实现该回调函数类型,并传递实际类型参数。

案例一。

打开delphi新建一个dll,源码如下:

library DLLEntry;

uses
  SysUtils,
  Windows,
  Dialogs,
  Classes;

{$R *.res}

procedure DLLEntryPoint(dwReason:DWord);  //入出口函数
 begin
   case dwReason of
     DLL_Process_Attach:showmessage(‘Attaching to process‘);
     DLL_PROCESS_DETACH:Showmessage(‘Detaching from process‘);
     DLL_THREAD_ATTACH:MessageBeep(0);
     DLL_THREAD_DETACH:MessageBeep(0);
   end;
 end;
begin
  DllProc:=@DLLEntryPoint;  //赋值给全局变量
  DLLEntryPoint(DLL_PROCESS_ATTACH);  //传DWord类型值
end.

调用dll,新建一个Delphi应用程序,在窗体上放置一个label和4个button控件。源码如下:

unit mainFrm;

interface

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

type

TTestThread=class(TThread)   //定义线程
    procedure Execute;override;
    procedure SetCaptionData;
  end;

TmainForm = class(TForm)
    btnLoadLib: TButton;
    btnFreeLib: TButton;
    btnCreateThread: TButton;
    btnFreeThread: TButton;
    lblCount: TLabel;
    procedure btnLoadLibClick(Sender: TObject);
    procedure btnFreeLibClick(Sender: TObject);
    procedure btnCreateThreadClick(Sender: TObject);
    procedure btnFreeThreadClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    LibHandle:THandle;
    TestThread:TTestThread;
    Counter:Integer;
    GoThread:Boolean;
  public
    { Public declarations }
  end;

var
  mainForm: TmainForm;

implementation

{$R *.dfm}

procedure TTestThread.Execute();   //重写线程的Execute方法
begin
   while mainForm.GoThread do
     begin
       Synchronize(SetCaptionData);
       Inc(mainForm.Counter);
     end;
end;

procedure TTestThread.SetCaptionData;    //线程的异步方法修改label控件的caption
begin
  mainForm.lblCount.Caption:=IntToStr(mainForm.Counter);
end;
procedure TmainForm.btnLoadLibClick(Sender: TObject);    //载入dll
begin
 if LibHandle=0 then
  begin
    LibHandle:=LoadLibrary(‘DLLEntry.dll‘);
    if LibHandle=0 then
     raise Exception.Create(‘Unable to Load DLL‘);
  end
 else
   MessageDlg(‘Library already loaded‘,mtWarning,[mbOK],0);
end;

procedure TmainForm.btnFreeLibClick(Sender: TObject);   //释放dll
begin
 if not (LibHandle=0) then
   begin
     FreeLibrary(LibHandle);
     LibHandle:=0;
   end;
end;

procedure TmainForm.btnCreateThreadClick(Sender: TObject);  //开启线程
begin
 if TestThread=nil then
   begin
     GoThread:=True;
     TestThread:=TTestThread.Create(False);
   end;
end;

温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/69848.html