• 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 UsesDll中,你的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);//
    先把dllMainForm句柄保存起来,也无须释放,只不过是替换一下
    ptr^:=LongInt(mainForm);//
    用主调程序的mainForm替换DLLMainFormMainForm是特殊的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;
  • 相关阅读:
    20171017/20171018
    BZOJ[3193] [JLOI2013]地形生成
    BZOJ[1009] [HNOI2008]GT考试
    BZOJ[4767] 两双手
    BZOJ[4013] [HNOI2015]实验比较
    BZOJ[1925] [Sdoi2010]地精部落
    20171015 杂题
    20171015
    20171014
    USACO 2015 December Contest, Gold Problem 3. Bessie's Dream
  • 原文地址:https://www.cnblogs.com/y232995558/p/1451210.html
Copyright © 2020-2023  润新知