Delphi之DLL知识学习4---创建DLL

  下面是在Delphi中创建一个DLL的全过程,你将看到怎样创建一个接口单元,使之可以被其他的应用程序访问。并且将学会怎么把Delphi的窗体加入DLL中。

  

一、数美分:一个简单的DLL

  下面是包含一个例程的DLL例子。该例程是将以美分计算的货币换算成五分镍币、一角硬币的数目。

1.一个简单的DLL

  该DLL中包含PenniesToCoins()函数,下面完整的显示了该DLL项目文件代码

library PenniesLib;
{$DEFINE PENNIESLIB}
uses
    SysUtils, Classes, PenniesInt;
function PenniesToCoins(TotPennies: word; CoinsRec: PCoinsRec): word; stdcall;
begin
    Result:= TotPennies;    //结果存放于Result
    {计算Quarters、Dimes、Nickels、Pennies的值}
    with CoinsRec^ do
    begin
        Quarters:= TotPennies div 25;
        TotPennies:= TotPennies - Quarters * 25;
        Dimes:= TotPennies div 10;
        TotPennies:= TotPennies - Dimes * 10;
        Nickels:= TotPennies div 5;
        TotPennies:= TotPennies - Nickels * 10;
        Pennies:= TotPennies;
    end;
end;

{引出函数名}
exports
    PenniesToCoins;

end.

  注意,该DLL使用了PenniesInt单元,这将在后面详细介绍

  在Exports子句引出了DLL中应用程序要调用的函数或过程

2.定义接口单元

  接口单元通过把引入单元的名字加入 uses子句中,实现调用DLL的应用程序能够静态地引入DLL的例程。接口单元也允许定义成DLL的调用应用程序都能使用的公共结构。下面就有一个接口单元论证了这点

unit PenniesInt;
{PENNIES.DLL的接口例程}

interface
type
    {这个记录将保存转换后的货币数}
    PCoinsRec = ^TCoinsRec;
    TCoinsRec = record
        Quarters,
        Dimes,
        Nickels,
        Pennies: word;
    end;

{$IFNDEF PENNIESLIB}
{由关键词export声明函数}
function PenniesToCoines(TotPennies: word; CoinsRec: PCoinsRec): word; Stdcall;
{ENDIF}

implementation
{$IFNDEF PENNIESLIB}
{定义引入的函数}
function PenniesToCoins; external 'PENNIESLIB.DLL' name 'PenniesToCoins';
{$ENDIF}

end.

  在这个项目中的type 部分,声明了一个叫 TCoinsRec的记录以及指向该记录的指针。这个记录保存传递给PenniesToCoins() 的货币数转换后的结果。函数PenniesToCoins() 带有两个传递参数:以美分为单位的货币数和指向TCoinsRec变量的指针。函数的返回值是换算后的货币数

  PenniesInt.pas 在其接口单元中声明了函数,该函数要从DLL中引出。PenniesToCoins() 函数的定义放在 implementation部分,这个定义指明该函数是存在于DLL文件(PenniesLib.dll)中的一个外部函数。链接是按函数的名称进行的。请注意:这里用了一条编译指令: PENNIESLIB,用于有条件的编译PenniesToCoins() 寒素的声明。这样做事因为在编译该接口单元时,对DLL来说,是没有必要编译函数的声明。这样,DLL和调用DLL的应用程序就可以共享接口单元,如果要改变二者使用的结构,只需要修改单元接口

  提示:要定义一个应用程序范围的条件指令,可以在Options对话框 Eirectories/Conditionals页上指定该条件。值得注意的是,为使该条件指令有效,必须重新编译程序项目,这是因为make逻辑中需要加上条件定义

  注意:下面定义是引入一个DLL例程的两种方法之一

function PenniesToCoins; external 'PENNIESLIB.DLL' index 1';

  这种方称为按序号引入,另一种方式是按名称引入

function PenniesToCoins; external 'PENNIESLIB.DLL' name 'PenniesToCoins';

  按名称引入时,紧跟在关键字 name后面的标识符就是例程在DLL中的名称

  因为按序号引入例程不必在DLL的名称表中查找,所以减少了DLL的调入时间。然而,在Win 32中,最好的方法不使用这个方法,而是按名称引入例程。因为当 DLL有所改动时,应用程序不必理睬DLL整体序号的变动。如果按序号引入,就捆绑到DLL的具体位置;如果按名称引入,则捆绑到例程名,而不必管它在DLL中的位置。

  如果把上面的DLL共享出去,就必须想你的用户提供 PenniesLib.dll 和PenniesInt.pas。 这样,就使他们可以通过定义这里有 PenniesLib.dll所要求在PenniesInt.pas中定义的类型和例程使用该DLL。

  再者如果程序员使用的是其他语言,譬如 C++ ,这就需要将PenniesInt.pas 转换为他所使用的语言,这样,在这些开发环境下才可以使用该 DLL

二、显示DLL中的模式窗体

  。。。。。。

三、显示DLL中的无模式窗体

  。。。。。。