入口点函数的名称无所谓只要您让语句“END<函数名>”中的函数名和前面的相同就可以了。该函数共有三个参数,只有前面两个是重要的。 hInstDLL是该动态链接库模块的句柄。它和进程的实例句柄不一样。如果您以后要用,可以保存它,因为以后再要获得它不容易。 根据不同的时机,reason传入的值可能是下面的四个值中的一个: DLL_PROCESS_ATTACH 动态链接库第一次插入进程的地址空间时。当传入的参数是该值时,您可以做一些初始化的工作。 DLL_PROCESS_DETACH 动态链接库从进程的地址空间卸出时。您可以在此做一些清理的工作。譬如:释放内存等。 DLL_THREAD_ATTACH 新线程生成。 DLL_THREAD_DETACH 线程销毁。 如果想要库中的代码继续执行,返回TRUE,否则返回FALSE,那样动态链接库就不会加载了。譬如:您想分配一块内存,如果不成功的话就退出,这时您就可以返回FALSE。那样动态链接库就不会加载了。 您可以加入的函数,它们的位置并不重要,把它们放在入口点函数的前面或后面都可以。只是如果您想要它们能被其它的程序调用的话,就必须把它们的名字放到模块定义文件(.def)中去。 动态链接库在它们自己的编译过程就需要,而不只是提供给其它要引用它的程序参考。他们如下: LIBRARY DLLSkeleton EXPORTS TestFunction 第一行是必须的。LIBRARY 定义了DLL的模块名称。它必须和动态链接库的名称相同。 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 invoke ExitProcess,NULL end start 使用LoadLibrary函数加载动态链接库,可能要自己多做一些工作,但是这种方法确实是提供了许多的灵活性。  
2/2 首页 上一页 1 2 |