Delphi笔记(整理)-DLL和BPL

动态调入库(dynamically loadable library)在Windows 下是一个动态链接库(dynamic-link library,DLL),
在Linux 下是一个共享目标库(shared object library)

导入过程或函数最简单的方法是用external 指示字声明它们,比如,
在Windows 下: procedure DoSomething; external ’MYLIB.DLL’;
在Linux 下: procedure DoSomething; external ’mylib.so’;

你可以直接调用操作系统的库函数来访问一个库中的例程,这些库函数包括LoadLibrary、FreeLibrary 和
GetProcAddress。在Windows 下,这些函数在Windows.pas 单元声明,在Linux 下,为了兼容性考虑,
它们在SysUtils.pas 单元实现,实际的Linux 例程是dlopen、dlclose 和dlsym(这些都在Kylix 的Libc 单
元声明)。此时,我们使用过程类型的变量来引用导入的例程。

当一个例程在exports 子句中列出时,它将被输出,它的格式如下
exports entry1, ..., entryn;

只有在Windows 下能使用索引说明符,它包括指示字index,后面跟一个介于1 到2,147,483,647 之间的
数字常量(为提高程序效率,使用较小的索引值)。若入口中没有指定索引,在输出表中例程被自动赋予
一个号码。

名称说明符包括指示字name,后面跟一个字符串常量。若入口没有名称说明符,例程被输出时使用声
明的原始名称,包括拼写和大小写。当要使用不同的名称输出一个例程时,使用name 子句。比如,
exports
DoSomethingABC name ’DoSomething’;

当在动态调入库中输出重载的函数或过程时,你必须在exports 子句中指定它的参数列表

exports 子句可出现在程序或库声明部分的任何位置,次数也不受限制,同样,当出现在单元的接口或实
现部分时,情况也是如此。程序很少包含exports 子句。

一个库的块(block)所包含的语句构成了库的初始化代码,每当库被调入时,这些代码执行一次。它们
的典型任务包括注册窗口类和初始化变量等。库的初始化代码也可以使用ExitProc 变量安装一个退出过
程(exit procedure),就像在Exit procedures 中描述的那样。退出过程在库被卸载时执行。
库的初始化代码通过设定ExitCode 变量为非0 来标记一个错误。ExitCode 在System 单元声明,默认值
时0。若库的初始化代码把ExitCode 设置为其它值,库将被卸载,调用程序被通知发生了错误。类似地,
若初始化代码执行中发生了未处理的异常,调用程序也将被通知调入库时失败。

在共享库中声明的全局变量不能被Object Pascal 程序导入。

使用IsLibrary 变量来确定代码是作为程序还
是库执行,IsLibrary 在程序中总是True,在库中总是False。在库的生命期内,HInstance 存储了它的
实例句柄,CmdLine 在库中总是nil。

DLLProc 变量允许一个库监测操作系统对它的入口点(entry point)的调用,这个特征通常只是由支持多
线程的库使用。DLLProc 在Windows 和Linux 下都存在,但用起来不同。在Windows 下,DLLProc 用
于多线程程序,在Linux 下,它用来判断库何时被卸载。对所有的退出行为,你应该使用finalization
sections,而不是退出过程。

在Windows 下,若DLL 输出的例程以长字符串或动态数组作为参数或者作为函数的返回值(不管是直
接的,还是通过记录或对象封装的),那么,DLL 和它的客户程序(或DLL)必须使用ShareMem 单元;
当一个程序或DLL 调用New 或GetMem 分配内存,而在另一个模块中调用Dispose 或FreeMem 来释放
内存时,上面的规则同样适用。ShareMem 单元应当在程序或库的uses 子句中第一个列出。
ShareMem 是BORLANDMM.DLL 内存管理器的接口单元,它允许在模块间共享动态分配的内存。
BORLANDMM.DLL必须连同使用ShareMem单元的程序和DLL一同发布。当程序或DLL使用ShareMem
时,它的内存管理器被BORLANDMM.DLL 中的取代。
Linux 使用glibc 的malloc 来管理共享内存。

为了区分包和其它库,包被存储在文件
• 在Windows 下,包的扩展名是.bpl(Borland package library)
• 在Linux 下,包通常以前缀bpl 开始,扩展名是.so。
通常,程序启动时包被静态调入,但你可以使用LoadPackage 和UnloadPackage 例程(在SysUtils 单元)
来动态调入包。

包源文件不包括类型、数据、过程或函数声明。取而代之的是,它包含
• 包的名称;
• 它所需要的其它包的列表。这些包被链接到新包中;
• 包被编译时所包含的(或绑定的)单元文件列表。包实际上是这些代码单元的一个外包装,这些单
元为编译后的包提供功能。
包的声明有如下形式:
package packageName;
requiresClause;
containsClause;
end.
package DATAX;
requires
baseclx,
visualclx;
contains Db, DBLocal, DBXpress, ... ;
end.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值