dll

表给我讲讲DLL最后能举例子,我是一个初学者

解决方案 »

  1.   

    看看这篇文章吧!
    《Delphi环境中编写调用DLL的方法和技巧》
    http://202.101.237.86/xiaohua/shownews.asp?newsid=274
      

  2.   

    用Delphi制作DLL  
    一  Dll的制作一般步骤  
    二  参数传递  
    三  DLL的初始化和退出清理[如果需要初始化和退出清理]  
    四  全局变量的使用  
    五  调用静态载入  
    六  调用动态载入  
    七  在DLL建立一个TForM  
    八  在DLL中建立一个TMDIChildForM  
    九  示例:  
    十  Delphi制作的Dll与其他语言的混合编程中常遇问题:  
    十一  相关资料  
     
    一  Dll的制作一般分为以下几步:  
    1  在一个DLL工程里写一个过程或函数  
    2  写一个Exports关键字,在其下写过程的名称。不用写参数和调用后缀。  
    二  参数传递  
    1  参数类型最好与window  C++的参数类型一致。不要用DELPHI的数据类型。  
    2  最好有返回值[即使是一个过程],来报出调用成功或失败,或状态。成功或失败的返回值最好为1[成功]或0[失败].一句话,与windows  c++兼容。  
    3  用stdcall声明后缀。  
    4  最好大小写敏感。  
    5  无须用far调用后缀,那只是为了与windows  16位程序兼容。  
     
    三  DLL的初始化和退出清理[如果需要初始化和退出清理]  
    1  DLLProc[SysUtils单元的一个Pointer]是DLL的入口。在此你可用你的函数替换了它的入口。但你的函数必须符合以下要求[其实就是一个回调函数]。如下:  
    procedure  DllEnterPoint(dwReason:  DWORD);far;stdcall;  
    dwReason参数有四种类型:  
    DLL_PROCESS_ATTACH:进程进入时  
    DLL_PROCESS_DETACH进程退出时  
    DLL_THREAD_ATTACH  线程进入时  
    DLL_THREAD_DETACH  线程退出时  
    在初始化部分写:  
       DLLProc  :=  @DLLEnterPoint;  
       DllEnterPoint(DLL_PROCESS_ATTACH);  
    2  如Form上有TdcomConnection组件,就Uses  Activex,在初始化时写一句CoInitialize  (nil);  
    3  在退出时一定保证DcomConnection.Connected  :=  False,并且数据集已关闭。否则报地址错。  
     
    四  全局变量的使用  
    在widnows  32位程序中,两个应用程序的地址空间是相互没有联系的。虽然DLL在内存中是一份,但变量是在各进程的地址空间中,因此你不能借助dll的全局变量来达到两个应用程序间的数据传递,除非你用内存映像文件。  
     
    五  调用静态载入  
    1  客户端函数声名:  
    1)大小写敏感。  
    2)与DLL中的声明一样。  
         如:  showform(form:Tform);Far;external'yproject_dll.dll';  
    3)调用时传过去的参数类型最好也与windows  c++一样。  
    4)调用时DLL必须在windows搜索路径中,顺序是:当前目录;Path路径;windows;widows\system;windows\ssystem32;  
     
    六  调用动态载入  
    1  建立一种过程类型[如果你对过程类型的变量只是一个指针的本质清楚的话,你就知道是怎么回事了]。如:  
    type  
         mypointer=procedure(form:Tform);Far;external;  
    var  
       Hinst:Thandle;  
       showform:mypointer;  
    begin  
         Hinst:=loadlibrary('yproject_dll');//Load一个Dll,按文件名找。  
       showform:=getprocaddress(Hinst,'showform');//按函数名找,大小写敏感。如果你知道自动化对象的本质就清楚了。  
       showform(application.mainform);//找到函数入口指针就调用。  
       Freelibrary(Hinst);  
    end;  
     
    七  在DLL建立一个TForM  
    1  把你的Form  Uses到Dll中,你的Form用到的关联的单元也要Uses进来[这是最麻烦的一点,因为你的Form或许Uses了许多特殊的单元或函数]  
    2  传递一个Application参数,用它建立Form.  
     
    八  在DLL中建立一个TMDIChildForM  
    1  Dll中的MDIForm.FormStyle不用为fmMDIChild.  
    2  在CreateForm后写以下两句:  
    function  ShowForm(mainForm:TForm):integer;stdcall  
    var  
       Form1:  TForm1;  
       ptr:PLongInt;  
    begin  
       ptr:=@(Application.MainForm);//先把dll的MainForm句柄保存起来,也无须释放,只不过是替换一下  
       ptr^:=LongInt(mainForm);//用主调程序的mainForm替换DLL的MainForm。MainForm是特殊的WINDOW,它专门管理Application中的Forms资源.  
    //为什么不直接Application.MainForm  :=  mainForm,因为Application.MainForm是只读属性  
       Form1:=TForm1.Create(mainForm);//用参数建立  
    end;  
    备注:参数是主调程序的Application.MainForm  
     
    九  示例:  
    DLL源代码:  
    library  Project2;  
     
    uses  
       SysUtils,  
       Classes,  
       Dialogs,  
       Forms,  
       Unit2  in  'Unit2.pas'  {Form2};  
     
    {$R  *.RES}  
    var  
       ccc:  Pchar;  
     
    procedure  OpenForm(mainForm:TForm);stdcall;  
    var  
       Form1:  TForm1;  
       ptr:PLongInt;  
    begin  
       ptr:=@(Application.MainForm);  
       ptr^:=LongInt(mainForm);  
       Form1:=TForm1.Create(mainForm);  
    end;  
     
    procedure  InputCCC(Text:  Pchar);stdcall;  
    begin  
       ccc  :=  Text;  
    end;  
     
    procedure  ShowCCC;stdcall;  
    begin  
       ShowMessage(String(ccc));  
    end;  
     
    exports  
       OpenForm;  
       InputCCC,  
       ShowCCC;  
    begin  
    end.  
     
    调用方源代码:  
    unit  Unit1;  
     
    interface  
     
    uses  
       Windows,  Messages,  SysUtils,  Classes,  Graphics,  Controls,  Forms,  Dialogs,  
       StdCtrls;  
     
    type  
       TForm1  =  class(TForm)  
           Button1:  TButton;  
           Button2:  TButton;  
           Edit1:  TEdit;  
           procedure  Button1Click(Sender:  TObject);  
           procedure  Button2Click(Sender:  TObject);  
       private  
           {  Private  declarations  }  
       public  
           {  Public  declarations  }  
       end;  
     
    var  
       Form1:  TForm1;  
     
    implementation  
     
    {$R  *.DFM}  
    procedure  OpenForm(mainForm:TForm);stdcall;External'project2.dll';  
    procedure  ShowCCC;stdcall;External'project2.dll';  
    procedure  InputCCC(Text:  Pchar);stdcall;External'project2.dll';  
     
    procedure  TForm1.Button1Click(Sender:  TObject);  
    var  
       Text:  Pchar;  
    begin  
       Text  :=  Pchar(Edit1.Text);  
    //    OpenForm(Application.MainForm);//为了调MDICHILD  
       InputCCC(Text);//为了实验DLL中的全局变量是否在各个应用程序间共享  
    end;  
     
    procedure  TForm1.Button2Click(Sender:  TObject);  
    begin  
       ShowCCC;//这里表明WINDOWS  32位应用程序DLL中的全局变量也是在应用程序地址空间中,16位应用程序或许不同,没有做实验。  
    end;  
     
    十  Delphi制作的Dll与其他语言的混合编程中常遇问题:  
    1  与PowerBuilder混合编程  
       在定义不定长动态数组方面在函数退出清理堆栈时老出现不可重现的地址错,原因未明,大概与PB的编译器原理有关,即使PB编译成二进制代码也如此。