exports关键字告诉链接器该dll的引出函数,也就是其它程序可以调用的函数。举个例子:其它的程序想要调用函数testfunction ,我们就把它放到exports中。
还有就是,链接器的选项中必须放入开关项:/dll 和/def<dll文件名>,就像下面这样:
link /dll /subsystem:windows /def:dllskeleton.def /libpath:c:\masm32\lib dllskeleton.obj
编译器的开关选项是一样的,即:/c /coff /cp。在您链接好后,链接器会生成.lib 和.dll文件。前者是引入库,当其它的程序要调用您的动态链接库中的函数时就需要该引入库,以便把必要的信息加入到其可执行文件中去。
接下来我们来看看如何使用loadlibrary函数来加载一个dll。
;---------------------------------------------------------------------------------------------
; usedll.asm
;----------------------------------------------------------------------------------------------
.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
.data
libname db "dllskeleton.dll",0
functionname db "testhello",0
dllnotfound db "cannot load library",0
appname db "load library",0
functionnotfound db "testhello function not found",0
.data?
hlib dd ? ; 动态链接库的句柄 (dll)
testhelloaddr dd ? ; testhello 函数的地址
.code
start:
invoke loadlibrary,addr libname
;---------------------------------------------------------------------------------------------------------
; 调用loadlibrary,其参数是欲加载的动态链接库的名称。如果调用成功,将返回该dll的句柄。 否则返回null。该句柄可以传给 :library函数和其它需要动态链接库句柄的函数。
;-----------------------------------------------------------------------------------------------------------
.if eax==null
invoke messagebox,null,addr dllnotfound,addr appname,mb_ok
.else
mov hlib,eax
invoke getprocaddress,hlib,addr functionname
;-----------------------------------------------------------------------------------------------------------
; 当您得到了动态链接库的句柄后,把它传给getprocaddress函数,再把您要调用的函数的名称 也传给该函数。如果成功的话,它:会返回想要的函数的地址,失败的话返回null。除非卸载该 动态链接库否则函数的地址是不会改变的,所以您可以把它保存到一个:全局变量中以备后用。
;-----------------------------------------------------------------------------------------------------------
.if eax==null
invoke messagebox,null,addr functionnotfound,addr appname,mb_ok
.else
mov testhelloaddr,eax
call [testhelloaddr]
;-----------------------------------------------------------------------------------------------------------
; 以后您就可以和调用其它函数一样调用该函数了。其中要把包含函数地址信息的变量用方括号括起来。
;-----------------------------------------------------------------------------------------------------------
.endif
invoke freelibrary,hlib
;-----------------------------------------------------------------------------------------------------------
;调用freelibrary卸载动态链接库。
;-----------------------------------------------------------------------------------------------------------
.endif