to zhaowin:这东西到处都是,留个email吧发给你。
 
Windows本身就是由大量的动态链接库支持的。这包括Windows API函数 ( KRNLx86.EXE,USER.EXE,GDI.EXE,…),各种驱动程序文件,各种带有.Fon和.Fot 扩展名的字体资源文件等。Windows还提供了针对某一功能的专用DLLs,如进行DDE编程的ddeml.dll,进行程序安装的ver.dll等。
  虽然在编写Windows程序时必然要涉及到DLLs,但利用Delphi ,用户在大部分时候并不会注意到这一点。这一方面是因为Delphi提供了丰富的函数使用户不必直接去使用Windows API;另一方面即使使用Windows API,由于Delphi把API函数和其它Windows DLLs函数重新组织到了几个库单元中,因而也不必使用特殊的调用格式。所以本章的重点放在编写和调用用户自定义的DLLs上。
  使用传统的Windows编程方法来创建和使用一个DLLs是一件很令人头痛的事,正如传统的Windows编程方法本身就令人生畏一样。用户需要对定义文件、工程文件进行一系列的修改以适应创建和使用DLLs的需要。Delphi的出现,在这一方面,正如在其它许多方面所做的那样,减轻了开发者的负担。更令人兴奋的是Delphi利用DLLs 实现了窗体的重用机制。用户可以将自己设计好的窗体储存在一个DLLs中,在需要的时候可随时调用它。10.2  DLLs的编写和调用10.2.1 DLLs的编写  在Delphi环境中,编写一个DLLs同编写一个一般的应用程序并没有太大的区别。事实上作为DLLs 主体的DLL函数的编写,除了在内存、资源的管理上有所不同外,并不需要其它特别的手段。真正的区别在工程文件上。
  在绝大多数情况下,用户几乎意识不到工程文件的存在,因为它一般不显示在屏幕上。如果想查看工程文件,则可以打开View菜单选择Project Source项,此时工程文件的代码就会出现在屏幕的Code Editor(代码编辑器)中。
  一般工程文件的格式为:  program    工程标题;
  uses     子句;
  程序体  而DLLs工程文件的格式为:  library    工程标题;
  uses       子句;
  exprots    子句;
  程序体  它们主要的区别有两点:
  1.一般工程文件的头标用program关键字,而DLLs工程文件头标用library 关键字。不同的关键字通知编译器生成不同的可执行文件。用program关键字生成的是.exe文件,而用library关键字生成的是.dll文件;
  2.假如DLLs要输出供其它应用程序使用的函数或过程,则必须将这些函数或过程列在exports子句中。而这些函数或过程本身必须用export编译指令进行编译。
  根据DLLs完成的功能,我们把DLLs分为如下的三类:
    1.完成一般功能的DLLs;
    2.用于数据交换的DLLs;
    3.用于窗体重用的DLLs。
  这一节我们只讨论完成一般功能的DLLs,其它内容将在后边的两节中讨论。10.2.1.1 编写一般DLLs的步骤  编写一般DLLs的步骤如下:
  1.利用Delphi的应用程序模板,建立一个DLLs程序框架。
  对于Delphi 1.0的用户,由于没有DLLs模板,因此:
  (1).建立一个一般的应用程序,并打开工程文件;
  (2).移去窗体和相应的代码单元;
  (3).在工程文件中,把program改成library,移去Uses子句中的Forms,并添加适当的库单元(一般SysUtils、Classes是需要的),删去begin...end之间的所有代码。
  2.以适当的文件名保持文件,此时library后跟的库名自动修改;
  3.输入过程、函数代码。如果过程、函数准备供其它应用程序调用,则在过程、函数头后加上export 编译指示;
  4.建立exports子句,包含供其它应用程序调用的函数和过程名。可以利用标准指示 name 、Index、resident以方便和加速过程/函数的调用;
  5.输入库初始化代码。这一步是可选的;
  6.编译程序,生成动态链接库文件。10.2.1.2 动态链接库中的标准指示  在动态链接库的输出部分,用到了三个标准指示:name、Index、resident。
  1.name
  name后面接一个字符串常量,作为该过程或函数的输出名。如: exports
InStr name MyInstr;  其它应用程序将用新名字(MyInstr)调用该过程或函数。如果仍利用原来的名字(InStr),则在程序执行到引用点时会引发一个系统错误。
  2.Index
  Index指示为过程或函数分配一个顺序号。如果不使用Index指示,则由编译器按顺序进行分配。
  Index后所接数字的范围为1...32767。使用Index可以加速调用过程。
  3.resident
  使用resident,则当DLLs装入时特定的输出信息始终保持在内存中。这样当其它应用程序调用该过程时,可以比利用名字扫描DLL入口降低时间开销。
  对于那些其它应用程序常常要调用的过程或函数,使用resident指示是合适的。例如: exports
InStr name MyInStr resident;