一、静态调用
静态调用(也称隐式链接),就是在程序开始执行时就将DLL文件加载到应用程序当中。执行的步骤如下:
1.首先生成一个项目TestDll,把你的MyDll.dll和MyDll.lib拷贝到你的目标工程的Debug目录下,也可以拷贝到Windows的System目录下;(Windows系统将遵循下面的搜索顺序来定位DLL:1.包含EXE文件的目录;2.当前工程的工作目录;3.Windows系统目录;4.Windows目录;5.列在Path环境变量中的一系列目录);
2.在DllTest.h和DllTest.cpp文件中分别输入如下代码:
//DllTest.h
#pragma comment(lib, "MyDll.lib")
extern "C" _declspec(dllimport) int Add(int a, int b);
extern "C" _declspec(dllimport) int Sub(int a, int b);
//DllTest.cpp
#include "DllTest.h"
#include <stdio.h>
int main()
{
int sum;
sum = Add(2, 3);
printf("求和的结果为:%d\n", sum);
}
DllTest.h中的关键字pragma comment是要Visual C++编译器在link时,链接到MyDll.lib文件。当然,我们也可以不使用#pragma comment(lib, "MyDll.lib")语句,而是直接打开工程的属性->链接器(Link)->输入,在附加依赖项中添加MyDll.lib即可。
补充:相应的,创建DLL中导出函数时,我们只需要在函数前面使用关键字 extern "C" _declspec(dllexport)。
二、动态调用
动态调用(也称显示链接),是应用程序再执行过程中随时可以加载DLL文件,也可以随时卸载DLL文件,这是隐式链接所无法做到的,所以显示链接具有更好的灵活性,对于解释性语言更为合适。
使用显示链接应用程序编译时不需要使用相应的lib文件,只需要将DLL文件拷贝到目标工程的Debug目录下。下面是通过显示链接调用DLL中函数的例子:
//将DLL加载到当前的应用程序并返回当前DLL文件的句柄;
HINSTANCE hDllInst = LoadLibrary("MyDll.dll");
if(hDllInst)
{
//定义指向和DLL中相同的函数原型指针;
typedef int (*MYFUNC)(int a, int b);
MYFUNC yourFunctionNameAlias = NULL; // yourFunctionNameAlias 函数别名
//获取导入到应用程序中的函数指针;
yourFunctionNameAlias = (MYFUNC)GetProcAddress(hDllInst, "yourFunctionName"); //yourFunctionName 在DLL中声明的函数名
if(yourFunctionNameAlias)
{
yourFunctionNameAlias(param1, param2);
}
//卸载DLL文件;
FreeLibrary(hDllInst);
}
另外,使用GetProcAddress()函数时,可以利用MAKEINTRESOURCE()函数直接使用DLL中函数出现的顺序号,如将GetProcAddress(hDllInst, "yourFunctionName") 改为GetProcAddress(hDllInst, MAKEINTRESOURCE(1)) (函数yourFunctionName()在DLL中的顺序号是2),这样调用DLL中的函数速度很快,但是要记住函数的顺序号,否则会发生错误。
【关于如何查看DLL文件导出函数的信息】
在Microsoft Visual Studio 10.0\VC\bin 目录下提供了dumpbin.exe程序,可以用来查看DLL文件中的函数结构:在Visual Studio命令行方式下,首先进入DLL文件所在目录下,输入以下命令回车: dumpbin -exports MyDll.dll,输出信息中列出了所有导出函数的序号及函数名。