zoukankan      html  css  js  c++  java
  • Delphi中DLL的其他应用

    http://blog.csdn.net/zhenghui1/article/details/6618273

    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;

    procedure TmainForm.btnFreeThreadClick(Sender: TObject);  //释放线程
    begin
     if  Assigned(TestThread)  then
       begin
         GoThread:=False;
         TestThread.Free;
         TestThread:=nil;
         Counter:=0;
       end;
    end;

    procedure TmainForm.FormCreate(Sender: TObject);   //初始化操作
    begin
      LibHandle:=0;
      TestThread:=nil;
    end;

    end.

    运行截图

        

     新建一个dll,源码如下:

        

    library StrSrchLib;


    uses
      SysUtils,
      Windows;

    {$R *.res}
      type
        TFoundStrProc=procedure (StrPos:PChar);stdcall;    //定义过程类型

      function SearchStr(ASrcStr,ASearchStr:PChar;AProc:TFarProc):Integer;stdcall;  //字符串查找功能
      var
        FindStr:PChar;
      begin
        FindStr:=ASrcStr;
        FindStr:=StrPos(FindStr,ASearchStr);  //查找ASearchStr在FindStr中出现位置
        while FindStr<>nil do      
         begin
           if AProc<>nil then
             TFoundStrProc(AProc)(FindStr);  //强制类型转换,将FindStr作为参数
             FindStr:=FindStr+1;
             FindStr:=StrPos(FindStr,ASearchStr);   //循环查找
         end;
      end;

      exports
       SearchStr;
    begin
    end.

    新建Delphi应用程序,在窗体上放置一个edit 一个memo和一个button控件,源代码如下:

    unit CallTest;

    interface

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

    type
      TMainForm = class(TForm)
        btnCallDLLFunc: TButton;
        lblSrchWrd: TLabel;
        mmoStr: TMemo;
        edtSearchStr: TEdit;
        procedure btnCallDLLFuncClick(Sender: TObject);
      end;

    var
      MainForm: TMainForm;
      count:integer;   //全局计数变量

    implementation

    {$R *.dfm}

    function SearchStr(ASrcStr,ASearchStr:PChar;AProc:TFarProc):Integer;stdcall;external 'StrSrchLib.dll';   //声明导入函数

    procedure  StrPosProc(AStrPsn:PChar);stdcall;   //具体的回调函数类型
    begin
      inc(count);
    end;

    procedure TMainForm.btnCallDLLFuncClick(Sender: TObject);
    var
      s,s2:string;
    begin
      count:=0;
      SetLength(s,mmoStr.GetTextLen);
      mmoStr.GetTextBuf(PChar(s),mmoStr.GetTextLen);    //这两句功能是将memo控件内容赋值给s字符串
      s2:=edtSearchStr.Text;
      SearchStr(PChar(s),PChar(s2),@StrPosProc);
      ShowMessageFmt('%s %s %d %s',[edtSearchStr.Text,'occurs',count,'times.']);
    end;

    end.

      

          DLL还有其他许多功能,在此不在一一列举,源码参考了delphi5编程指南,在Delphi7下编译运行通过,关于DLL还需在项目中更多应用才可熟能生巧。

  • 相关阅读:
    浅析Python中bytes和str区别
    Python面对对象相关知识总结
    Django实现微信公众号简单自动回复
    阿里云部署django实现公网访问
    JDBC学习笔记(1)——JDBC概述
    Java单元测试初体验(JUnit4)
    Java设计模式系列之动态代理模式(转载)
    Java设计模式系列之责任链模式
    Java设计模式系列之观察者模式
    局部内部类和匿名内部类的对比
  • 原文地址:https://www.cnblogs.com/tc310/p/4643602.html
Copyright © 2011-2022 走看看