WIN32汇编语言教程:第11章 动态链接库和钩子 · 11.1 动态链接库(3)
11.1.3 使用动态链接库
虽然在前面的学习中一直在使用动态链接库,但本节仍然要介绍一下使用动态链接库的方法,这是为了比较全面地介绍使用动态链接库的不同途径和它们之间的区别。相关的例子文件包含在所附光盘的Chapter11\Dll目录中。在开始分析例子之前,首先要把上一节中生成的相关文件拷贝到本目录中以便使用,它们是Counter.dll,Counter.lib和Counter.inc文件。
例子包括两个不同的程序UseDll1和UseDll2,分别用来演示使用DLL的两种方法。两个例子文件使用了同样的资源定义文件UseDll.rc,所以它们的界面是一样的,事实上,它们完成的功能也是一样的,仅实现的方法不同而已,UseDll.rc文件的内容如下:
//##################################################################
#include <resource.h>
//##################################################################
#define ICO_MAIN 1000
#define DLG_MAIN 1000
#define IDC_COUNT 1001
#define IDC_INC 1002
#define IDC_DEC 1003
//##################################################################
ICO_MAIN ICON "Main.ico"
//##################################################################
DLG_MAIN DIALOG 186, 132, 173, 44
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "DLL例子"
FONT 9, "宋体"
{
LTEXT "当前计数", -1, 6, 9, 37, 8
EDITTEXT IDC_COUNT, 45, 7, 69, 12, ES_READONLY
PUSHBUTTON "增加(&A)", IDC_INC, 121, 6, 46, 14
PUSHBUTTON "减少(&D)", IDC_DEC, 121, 23, 46, 14
}
//##################################################################
资源中定义了一个如图11.1所示的对话框,上面设计了两个按钮,分别用来调用Counter.dll中的_IncCount和_DecCount函数,这两个函数将DLL内部计数器中的计数进行增减计算,并将结果显示在对话框上的编辑框中。

图11.1 DLL使用例子的运行界面
1. 方法一:常规方法
先看UseDll1.asm程序,这个程序用常规的方法实现了对Counter.dll动态链接库中函数的调用:
.386
.model flat, stdcall
option casemap :none
;####################################################################
; Include 文件定义
;####################################################################
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
include Counter.inc
includelib Counter.lib
;####################################################################
; Equ 等值定义
;####################################################################
ICO_MAIN equ 1000
DLG_MAIN equ 1000
IDC_COUNTER equ 1001
IDC_INC equ 1002
IDC_DEC equ 1003
;####################################################################
; 代码段
;####################################################################
.code
;####################################################################
_ProcDlgMain proc uses ebx edi esi hWnd,wMsg,wParam,lParam
mov eax,wMsg
;********************************************************************
.if eax == WM_CLOSE
invoke EndDialog,hWnd,NULL
;********************************************************************
.elseif eax == WM_COMMAND
mov eax,wParam
.if ax == IDC_INC
invoke _IncCount,hWnd,IDC_COUNTER
.elseif ax == IDC_DEC
invoke _DecCount,hWnd,IDC_COUNTER
.endif
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
_ProcDlgMain endp
;####################################################################
start:
invoke GetModuleHandle,NULL
invoke DialogBoxParam,eax,DLG_MAIN,NULL,\
offset _ProcDlgMain,NULL
invoke ExitProcess,NULL
;####################################################################
end start
这段代码是再简单不过的了,读者只需要注意两点。首先是程序开头的包含语句:
include Counter.inc includelib Counter.lib
第二点就是WM_COMMAND消息中调用_IncCount和_DecCount函数的方法,毋需多言,方法和使用Windows提供的DLL时是一模一样的。
那么,这种方法有什么缺点呢?先来做几个实验。首先,将Counter.dll文件删除,再执行UseDll1.exe文件,这时对话框并没有被显示,系统弹出如图11.2所示的错误提示框。

图11.2 丢失Dll文件时的错误信息
这说明不管程序要用到哪几个dll文件,如果丢失任何一个dll文件的话(UseDll1.exe文件中还用到了Kernel32.dll文件和User32.dll文件,它们并没有丢失),可执行文件将无法被装入执行。
上页:第11章 动态链接库和钩子 · 11.1 动态链接库(2) 下页:第11章 动态链接库和钩子 · 11.1 动态链接库(4)