新建--win32项目--DLL--空项目,在源文件目录下新建一个cpp文件,随便编写两个简单函数,代码如下:
int add(int a, int b) { return a + b; } int subtract(int a, int b) { return a - b; }
然后按 F7 生成,结果如下:
生成了一个 dll 文件,但是这个文件并没有声明函数导出,可以借助 dumpbin.exe 程序来查看 dll 文件是否有函数导出以及导出了哪些函数。
在 D:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin 目录下有一个 vcvars32.bat 批处理程序,用于暂时配置使用例如 dumpbin.exe 类似的程序,打开命令提示符 cmd,切换到上面新建的动态链接库项目的 Debug 目录下:
然后直接将 vcvars32.bat 拖拽到cmd中:
Enter 回车运行,没有任何其他显示,则运行正常:
然后输入 dumpbin,回车:
说明dumpbin.exe 程序可以正常运行,现在回车后继续,使用 dumpbin -exports *.dll 命令来查看 dll 文件的函数导出情况:
如上图,dll 文件在没有函数导出声明的情况下是没有任何函数导出的。需要加入如下代码:
_declspec(dllexport) int add(int a, int b) { return a + b; } _declspec(dllexport) int subtract(int a, int b) { return a - b; }
这时重新生成后,如下:
多了一个引入库文件 lib 文件和一个 exp 文件(在使用动态库的时候没用,编译链接的中间文件)。
这时,再运行一下dumpbin 看看结果:
这样就说明 dll 文件可以成功的导出函数了,ordinal是函数的序号,hint是标识(然并卵),RVA是地址,name函数名加入和一些符号,因为C++中支持函数重载,为了区分相同名字的函数的用处。并且,不同的C++编译器对于这种名字的改编方式不一样。
现在我们编写客户端程序来调用刚刚编写的动态链接库文件,同样新建一个简单的控制台程序:
#include <iostream> using namespace std; extern int add(int a, int b); extern int subtract(int a, int b); int main() { cout << add(5, 3) << endl; return 0; }
因为 add 和 subtract 函数都是外部调用,因此用 extern 关键字来声明这两个函数,但是在生成的时候报出了 Link 错误:
之所以会这样是因为在编译的时候,因为提前对两个函数做出了声明,所以没有编译错误,但是在链接的时候,编译器无法找到这两个函数是在什么位置导出的。
现在我们将之前在 Dll-Test 项目中生成的 Dll-Test.lib 引入库文件拷贝到 Dll-Client 目录下,并且在Dll-Client 项目的属性设置中加入对 Dll-Test.lib 文件的引用:
再次生成,就没有报错了:
并且,我们也可以借助 dumpbin 工具来查看我们的 Dll-Client 程序使用了那些动态链接库,在cmd 中切换到Dll-Client 目录下:
我们可以看到,Dll-Client.exe 这个程序使用到了那些 dll 文件。
版权声明:本文为博主原创文章,未经博主允许不得转载。