MFC扩展DLL与常规DLL
MFC提供了三种不同的方式支持DLL的开发:
1.建立静态链接MFC的常规DLL(Regular DLL)
2.建立动态链接MFC的常规DLL
3.建立动态链接MFC的扩展DLL(Extension DLL)
扩展DLL与常规DLL的区别在于:
(1)MFC的扩展DLL支持C++接口,即扩展DLL能够导出整个C++类。这就是说,我们可以从已有的MFC类派生新的可再用类。扩展DLL在建立时使用的是MFC的动态链接,因而扩展DLL要求客户程序动态地链接到MFC动态库。扩展DLL的一个特点是尺寸很小,能够很快加载。
(2)常规DLL可被任意win32编程环境加载。它的局限性在于常规DLL只能导出标准C接口,不能导出C++类。但在常规DLL内部,仍然可以使用C++类及MFC类。
(3)常规DLL能够采用显式链接或隐式链接,而扩展DLL只能采用显示链接。
静态链接MFC的DLL与动态链接MFC的DLL的区别在于:
(1)静态链接MFC的DLL将拷贝所有需要的MFC的代码,成为自我包含的模块,可独立于MFC的DLL库而运行,但DLL的代码尺寸会较大。
(2)动态链接MFC的DLL在运行时动态链接MFC类库,因而DLL的代码尺寸会大大减小,但必须确保在运行的系统上有合适版本的MFC DLL库。
显式链接或隐式链接
理论:调用动态DLL有两种方法:一种是隐式链接,一种是显式链接,如果用loadlibrary方式就是显示链接,用.h、.lib、.dll三件套就属于隐式链接。
一:隐式链接:
隐式链接采用静态加载的方式,比较简单,需要.h、.lib、.dll三件套。新建“控制台应用程序”或“空项目”。配置如下:
项目->属性->配置属性->VC++ 目录-> 在“包含目录”里添加头文件xxx.h所在的目录
项目->属性->配置属性->VC++ 目录-> 在“库目录”里添加头文件xxx.lib所在的目录
项目->属性->配置属性->链接器->输入-> 在“附加依赖项”里添加“xxx.lib”(若有多个 lib 则以空格隔开)。
注:也可以在代码中添加一行设置库的链接,
#pragma comment(lib, “xxx.lib”)
隐式链接和vs加载配置opencv很像,不做实例展示。
二:显式链接:
今天发现,可以用函数指针来调用dll。
调用步骤:
1、声明头文件<windows.h>,说明我想用windows32方法来加载和卸载DLL
注:如果使用了opencv,不能使用using namespace cv,可能和windows.h里面的命名空间冲突,必须使用cv:: 。
2、然后用typedef定义一个指针函数类型.typedef void(*fun) //这个指针类型,要和你调用的函数类型和参数保持一致
3、定一个句柄实例,用来取DLL的实例地址。HINSTANCE hdll;
格式为hdll=LoadLibrary(“DLL地址”);你封装的dll路径名称
要配置-属性-常规里面把默认字符集“unicode”改成支持多字符扩展。
4、取的地址要判断,定义一个函数指针,用来获取你要用的函数地址。
然后通过Win32 API 函数GetProcAdress来获取函数的地址,参数是DLL的句柄和你要调用的函数名:比如:FUN=(fun)GetProcAdress(hdll,”My_dll”);
要判断要函数指针是否为空,如果没取到要求的函数,那么要释放句柄。
6、然后通过函数指针来调用函数。
7、调用结束后,就释放句柄FreeLibrary(hdll);
实例展示:
封装:
#include <string>
extern "C" __declspec(dllexport) int My_add(int a,int b)
{
printf("%d\n",a+b);
return a + b;
}
extern "C" __declspec(dllexport) int My_sub(int a, int b)
{
printf("%d\n", a - b);
return a - b;
}
调用:
#include <string>
#include "Windows.h"
typedef int(*Dllfun)(int, int);
//using namespace std;
//using namespace cv;
int main()
{
Dllfun funName;
HINSTANCE hdll;
//put DLL under the release path
hdll = LoadLibrary(("ThreadLocal.dll"));
if (hdll == NULL)
{
FreeLibrary(hdll);
}
funName = (Dllfun)GetProcAddress(hdll, "My_add");//My_sub
if (funName == NULL)
{
FreeLibrary(hdll);
}
int x = 1, y = 10;
int z = funName(x, y);
printf("z= %d\n", z);
FreeLibrary(hdll);
return 0;
}
自己定义的加法,LoadLibrary GetProcAddress 看起来麻烦,可是省去了头文件和lib的加载,更改接口测试方便,移植到Ubuntu和cent os也方便。

发表回复