Dll动态链接库创建与隐式链接方式使用
C++动态链接库的背景:
windows操作系统诞生以来,dll就作为win操作系统的基础,通常情况下dll不能直接运行,也无法接收消息,只能供其他可执行程序或者dll来调用,完成某项功能,他的函数只有被调用才会发挥作用,Windows中有三个重要的dll,他们分别是Kernal32.dll,User32.dll,GDI32.dll。
作用:
隐藏实现细节,再提供给三方客户端使用,便于保护私密信息。
提供二次开发等。
创建方式:
1、宏定义的方式声明方法名
2、使用模块定义文件定义导出函数的方式
查看:
visual studio安装之后,会自带“vs 2017开发人员命令提示符”终端,里面可以直接运行dumpbin命令。另一种办法是进入visual studio安装
目录下的一个工具目录,如我的安装在:D:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.13.26128\bin
\Hostx64\x64。进入该目录,就可以使用dumpbin命令了。
方法名问题:
默认如果不做任何处理,生成的动态链接库可以导出函数,但是函数名会出现特殊字符。并不是我们在源文件中定义的方法名,因此需要对函数声明做一些处理。还有一种方法就是通过模块定义文件的方式生成dll,这样方法名就不存在改变的问题了。
使用方式:
隐式链接和动态加载
介绍第一种方式创建动态链接库并使用隐式链接的方式使用dll。
1、创建dll工程。
2、编写头文件。
#ifdef DLL_API1 #else #define DLL_API1 extern "C" _declspec(dllimport) #endif DLL_API1 int add(int a, int b); DLL_API1 int substract(int a, int b);
3、编写源文件。
#include "stdafx.h" #define DLL_API1 extern "C" _declspec(dllexport) #include "dll2.h" int add(int a, int b) { return a + b; } int substract(int a, int b) { return a - b; }
4、生成。右键项目名->生成。我这里设置活动解决方案配置的是Release,活动解决方案平台采用的是x64。
1>------ 已启动生成: 项目: Dll2, 配置: Release x64 ------ 1>stdafx.cpp 1>Dll2.cpp 1>dllmain.cpp 1> 正在创建库 D:\feiy\workspace\vs\tutorials3\x64\Release\Dll2.lib 和对象 D:\feiy\workspace\vs\tutorials3\x64\Release\Dll2.exp 1>正在生成代码 1>All 3 functions were compiled because no usable IPDB/IOBJ from previous compilation was found. 1>已完成代码的生成 1>Dll2.vcxproj -> D:\feiy\workspace\vs\tutorials3\x64\Release\Dll2.dll ========== 生成: 成功 1 个,失败 0 个,最新 0 个,跳过 0 个 ==========
5、通过dumpbin查看生成的dll。dumpbin是visual studio提供的一个可以查看动态链接库导入导出信息。这里不做详细介绍。
启动->所有程序->Visual Sdudio 2017->Visual Studio Tools->VS 2017的开发人员命令提示符,输入dumpbin -export path/to/xxx.dll
D:\Program Files (x86)\Microsoft Visual Studio\2017\Community>dumpbin -exports D :\feiy\workspace\vs\tutorials3\x64\Release\Dll2.dll Microsoft (R) COFF/PE Dumper Version 14.13.26129.0 Copyright (C) Microsoft Corporation. All rights reserved. Dump of file D:\feiy\workspace\vs\tutorials3\x64\Release\Dll2.dll File Type: DLL Section contains the following exports for Dll2.dll 00000000 characteristics FFFFFFFF time date stamp 0.00 version 1 ordinal base 2 number of functions 2 number of names ordinal hint RVA name 1 0 00001000 add = add 2 1 00001010 substract = substract Summary 1000 .data 1000 .pdata 1000 .rdata 1000 .reloc 1000 .rsrc 1000 .text
从输出内容看,dll导出了我们定义的两个函数add,substract,验证了动态链接库创建成功。接下来就是通过程序来调用动态链接库了。
7、新建console工程,加入dll,lib文件到项目中。
这里需要将Dll2.dll,Dll2.lib文件都拷贝到项目路径下。还需要在资源文件上执行右键->添加->现有项,找到Dll2.lib文件导入。
8、编写测试源文件,并运行。我这里是在一个解决方案下的多个项目,所以没有直接将头文件dll2.h放入当前项目中,而是直接根据路径引入Dll2项目下的dll2.h头文件。
#include <iostream> #include "../Dll2/dll2.h" using namespace std; int main() { int sum = add(5, 2); cout << "add(5,2)= " << sum << endl; int sub = substract(5, 2); cout << "substract(5,2): " << sub << endl; return 0; }
运行结果: