第一个DLL程序:动态链接库DLL教程

DLL 程序的入口函数是 DllMain(),就像 DOS 程序的入口函数是 main()、Win32 程序的入口函数是 WinMain() 一样。前面我们一直在讲的就是DOS程序。

DllMain() 函数的原型为:
   
   
  1. BOOL APIENTRY DllMain(
  2. HANDLE hModule,
  3. DWORD ul_reason_for_call,
  4. LPVOID lpReserved
  5. );
其中:
  • hModule 表示本DLL程序的句柄。
  • ul_reason_for_call 表示DLL当前所处的状态,例如DLL_PROCESS_ATTACH表示DLL刚刚被加载到一个进程中,DLL_PROCESS_DETACH表示DLL刚刚从一个进程中卸载。
  • lpReserved 表示一个保留参数,目前已经很少使用。

一个简单的DLL程序并不比 "Hello World" 程序难,下面就开始介绍如何利用VS2008创建DLL及其调用方式。

首先利用VS2008新建一个 Win32 Dynamic-Link Library 类型的工程,工程取名为 dllDemo,并选择“An empty Dll project"选项,即创建一个空的动态链接库工程。然后,为该工程添加 一个C++源文件 main.c,并在其中编写完成加法运算和减法运算的函数,代码如下所示:
   
   
  1. #include <objbase.h> //也可以是windows.h #include <stdio.h> extern "C" __declspec(dllexport)int add(int a, int b){     return a+b; } extern "C" __declspec(dllexport)int sub(int a, int b){     return a-b; } BOOL APIENTRY DllMain(     HANDLE hModule,     DWORD  ul_reason_for_call,     LPVOID lpReserved ){     if(ul_reason_for_call == DLL_PROCESS_ATTACH){         printf("Congratulations! DLL is loaded!");     } }
然后利用Build命令生成dllDemo这一动态链接库程序。之后,在该工程的Debug目录下, 可以看到有一个dllDemo.dll文件,这就是生成的动态链接库文件。

读者要记住,应用程序如果想要访问某个DLL中的函数,那么该函数必须是已经被导出的函数。为了导出一些函数,需要在函数前面添加标识符 _declspec(dllexport)。

为了查看一个DLL中有哪些导出函数,可 以利用VS2008提供的命令行工具Dumpbin来实现。

Dumpbin.exe文件位于VS2008安装目录下的 common7/Tools目录下。在该目录下还有 一个批处理文件VCVARS32.bat,该文件的作用是用来建立VS2008使用的环境信息。如果读者在其他目录下无法执行Dumpbin命令,原因可能就是你的VS2008安装的环境信息被破坏了,那么可以运行VCVARS32.bat这个批处理文件,之后在其他目录下,就可以 执行Dumpbin命令了。

注意:当在命令行界面下执行VCVARS32.bat文件后,该文件所设置的环境信息只是在当前命令行窗口生效。如果关闭该窗口,并再次启动一个新的命令行窗口后,仍需要运行VCVARS32.bat文件。我当前的版本是VS2008,在VS安装目录下的common7/Tools目录下找到该BAT文件后直接拖到CMD命令行中运行即可。

在命令行界面下,cd 到工程目录下的debug目录,输入dumpbin -exports dllDemo.dll 命令,然后回车,即可查看DLL中的导出函数,如下图:


注意红色方框标出的信息:
ordinal    hint     RVA                name
          1         0     00001005        add
          2         1     0000100A        sub

在这段信息中,"ordinal" 列列出的信息 '1' 和 '2' 是导出函数的序号;"hint" 列列出的数字是提示码,该信息不重要;"RVA" 列列出的地址值是导出函数在DLL模块中的位置,也就是说,通过该地址值,可以在DLL中找到它们;最后一列 "name" 列出的是导出函数的名称。

将 add 函数前面的 _declspec(dllexport) 标识符去掉,再次编译 dllDemo 工程,然后执行 dumpbin -exports dllDemo.dll 命令,输出如下图所示:


可以看到,add 函数已经不是导出函数了。

打开项目目录下的Debug目录,发现有 dllDemo.dll 和 dllDemo.lib 两个文件。上节已经说过,.lib 文件包含DLL导出的函数和变量的符号名,.dll 文件才包含实际的函数和数据。主程序调用 DLL 需要这两个文件,下节会讲解如何使用。

注意:DllMain() 函数在DLL程序载入和卸载时执行,可以用来做一些初始化和清理的工作,如果仅仅是向外暴露函数,就可以省略 DllMain() 函数。但是如果有 DllMain() 函数,就一定要 #include <objbase.h>  或 #include <windows.h>。

例如,上面DLL如果只想暴露 add() 和 sub() 函数,而不想进行其他操作,那么可以这样写:

 
 
  1. _declspec(dllexport) int add(int a, int b){
  2. return a+b;
  3. }
  4. _declspec(dllexport)int sub(int a, int b){
  5. return a-b;
  6. }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值