内容来源于《Visual Basic 串口通信与测控》及网络
DLL 简介
动态链接库DLL(Dynamic Link Libaray)是一个函数库,是可被其它程序或DLL调用的函数集组成的可执行文件模块。之所以被称为动态链接库,是因为DLL的代码并不是某个应用程序的组成部分,而是在运行时链接到应用程序中的。例如,在 Windows 操作系统中,Comdlg32 DLL 执行与对话框有关的常见函数,因此每个程序都可以使用该 DLL 中包含的功能来实现“打开”对话框,这有助于促进代码重用和内存的有效使用。
动态链接分为两个阶段,链接过车装入过程。
当应用程序调用动态链接库中的某个函数时,链接程序并不会拷贝被调用函数的代码,而只是从引入库中拷贝一些指示信息,指出被调用函数属于哪个DLL文件,因此,在应用程序的可执行文件中,存放的不是被调用函数的代码,而是DLL中该函数的内存地址。程序运行后,当需要该函数时,进入装入过程,把应用程序与DLL库一起装入内存,由Windows读入DLL中的函数并运行程序。
因此,动态链接是在应用程序被装入到内存时进行的,当多个应用程序调用库中的同一个函数时,不会再内存中有该函数的多个拷贝,而只有一份拷贝,每个应用程序的的可执行文件中装入的只是该函数的内存地址,程序运行时再把应用程序代码与被调用函数代码动态链接起来,从而可以节省内存空间。同时,由于DLL与应用程序分开,即使更新DLL,也不用修改已编译好的可执行文件。
Windows API中所有的函数都包含在dll中,其中有3个最重要的DLL。
(1) Kernel32.dll
它包含那些用于管理内存、进程和线程的函数,例如CreateThread函数;
(2) User32.dll
它包含那些用于执行用户界面任务(如窗口的创建和消息的传送)的函数,例如CreateWindow函数;
(3) GDI32.dll
它包含那些用于画图和显示文本的函数。
DLL 的优点
•使用较少的资源
当多个程序使用同一个函数库时,DLL 可以减少在磁盘和物理内存中加载的代码的重复量。这不仅可以大大影响在前台运行的程序,而且可以大大影响其他在 Windows 操作系统上运行的程序。
•推广模块式体系结构
DLL 有助于促进模块式程序的开发。这可以帮助您开发要求提供多个语言版本的大型程序或要求具有模块式体系结构的程序。模块式程序的一个示例是具有多个可以在运行时动态加载的模块的计帐程序。
•简化部署和安装
当 DLL 中的函数需要更新或修复时,部署和安装 DLL 不要求重新建立程序与该 DLL 的链接。此外,如果多个程序使用同一个 DLL,那么多个程序都将从该更新或修复中获益。当您使用定期更新或修复的第三方 DLL 时,此问题可能会更频繁地出现。
DLL 依赖项
当某个程序或 DLL 使用其他 DLL 中的 DLL 函数时,就会创建依赖项。因此,该程序就不再是独立的,并且如果该依赖项被损坏,该程序就可能遇到问题。例如,如果发生下列操作之一,则该程序可能无法运行:
•依赖 DLL 升级到新版本。
•修复了依赖 DLL。
•依赖 DLL 被其早期版本覆盖。
•从计算机中删除了依赖 DLL。
DLL 应用
VB中创建的DLL只是COM组件,无法作为输出函数的DLL,其实这只是个错误的说法。其实MS非常狡猾,如果你是个VB疯狂发烧友的话,应该早就狂试出这种可以创建输出函数的DLL的方法。
VB编译文件实际上采取了两次编译的方法,首先是调用C2.exe产生*.OBJ文件,然后调用Link.EXE连接。如果在LINK的时候添加EXPORT选项,实际上是可以输出函数的。但是,在VB的工程选项中将这些屏蔽了。而且过分的是:VB在Build完成后会将OBJ文件删除,这样就无法手动通过Link来创建我们需要的DLL了。不过我找到一个比较龌鹾的变通的方法,就是
(1)先创建一个Exe工程,在Form_Load事件里面写下面的语句:
Sub Main
If MsgBox("哈哈", vbOKCancel) = vbOK Then
Shell "link2.exe " & Command$
End If
End Sub
(2)编译为LinkTemp.EXE,
(3)将LINK.EXE改名为Link2.exe,将LinkTemp.EXE改名为Link.EXE。这样在VB调用Link.EXE时会弹出对话框,处理就会中断。这时就可以有机会将OBJ文件拷贝出来了。
(4)创建一个ActiveX DLL工程,在这个工程里面添加一个Module并创建一个Public函数mathadd:
Public Function mathadd(ByVal a As Long, ByVal b As Long) As Long
mathadd = a + b
End Function
(5)编译这个工程,在Link的时候就会中断。然后把创建的Class1.obj、Module1.obj、Project1.obj备份出来。
(6)然后就可以调用Link2.exe连接OBJ到DLL了,连接代码是:
Link2.exe "e:/vbdll/Class1.obj" "e:/vbdll/Module1.obj" "e:/vbdll/Project1.obj" "E:/Program Files/Microsoft Visual Studio/VB98/VBAEXE6.LIB" /ENTRY:__vbaS /EXPORT:mathadd /OUT:"e:/vbdll/ProjectOK.dll" /BASE:0x11000000 /SUBSYSTEM:WINDOWS,4.0 /VERSION:1.0 /Dll /INCREMENTAL:NO /OPT:REF /MERGE:.rdata=.text /IGNORE:4078
注意里面的/ENTRY和/EXPORT开关,/EXPORT开关声明了输出函数mathadd。这样就大功告成了,可以被其他语言引入,例如在VB中,只需要:
Private Declare Function mathadd Lib "e:/vbdll/ProjectOK.dll" (ByVal a As Long, ByVal b As Long) As Long
经过变通,VB可以做出输出函数的标准动态链接库.