VS2015动态库编程之Win32动态库的使用(下)

文章相关视频教程下载地址:http://pan.baidu.com/s/1skKSrSh

 

 

4 动态库的加载及调用

 

动态库的加载分为静态加载、动态加载两种方式。

4.1 静态加载动态库

静态加载动态库的步骤包括:设置项目附加库目录;设置项目附加依赖项;移动DLL文件以及声明动态库的导出函数。

创建基于对话框的MFC项目,其项目名为Use_DLL_Test。其界面布局及控件ID如图4-1所示。其中,IDC_EDIT_ADD1和IDC_EDIT_ADD2用来输入两个加数;当点击IDC_BUTTON_ADD按键后,调用Win32_DLL_Test.dll中的导出函数add(),实现两个加数和的运算,并将和在IDC_EDIT_RESULT中显示出来。

图4-1 Use_DLL_Test界面布局

4.1.1 设置项目附加库目录

要在Use_DLL_Test项目中使用动态库Win32_DLL_Test.dll中的导出函数add(),必须指定Use_DLL_Test项目的附加库目录。程序在运行时,就会根据指定的附加库目录搜索所需的库文件。

在VS2015界面中选择菜单栏“项目->Use_DLL_Test属性”,之后在弹出的“Use_DLL_Test属性页”对话框的左侧栏中选择“配置属性->链接器->常规”,之后在右侧的“附加库目录”栏中,添加在前文创建的动态库文件所在的路径,如图4-2所示。

 

图4-2 设置项目的附加库目录

4.1.2 设置项目的附加依赖项

在设置了项目附加库目录之后,还需要设置项目的附加依赖项,即动态库的lib引入库文件名。可以通过两种方法对附加依赖项进行设置:一种是通过项目属性对话框设置,另一种是通过#pragma comment预编译宏进行设置。

(1)通过项目属性对话框设置

在“Use_DLL_Test属性页”对话框的左侧栏中选择“配置属性->链接器->输入”,在右侧的“附加依赖项”中输入动态库的lib引入库文件名Win32_DLL_Test.lib,如图4-3所示。

 

图4-3 设置项目的附加依赖项

(2)通过#pragma comment预编译宏进行设置

在Use_DLL_Test.cpp源文件的起始位置处,使用#pragma comment预编译宏,来设置项目的附加依赖项:

#pragma comment(lib, "Win32_DLL_Test.lib")

4.1.3 移动DLL文件

接下来要将Win32_DLL_Test.DLL文件拷贝到Use_DLL_Test项目所在的源代码路径下,或者将Win32_DLL_Test.DLL文件直接导入到Use_DLL_Test项目中。

将DLL文件导入到项目中的方法是在VS2015的界面中,选择左侧的“解决方案资源管理器”,之后选择“资源文件”,在鼠标右键菜单中选择“添加->现有项”,在“添加现有项”对话框中选择Win32_DLL_Test.DLL。添加完成之后,就可以看到在“资源文件”中就包含了Win32_DLL_Test.DLL,如图4-4所示。

图4-4 将DLL添加到项目中

4.1.4 声明函数

在Use_DLL_Test项目中,使用add()函数之前,要对其进行声明。可以使用extern或者_declspec进行声明。

在Use_DLL_Test.cpp的起始位置处使用如下代码进行声明:

extern unsigned int add(unsigned int x, unsigned int y);

或者

_declspec(dllimport)unsigned int add(unsigned int x, unsigned int y);

其中,extern是C++的关键字,用于声明而不是定义。声明不分配存储空间,它只是说明变量/函数定义在其它地方。_declspec(dllimport)表示其修饰的函数是动态库的导出函数,在其他程序中使用该函数。

4.1.5 调用函数

在IDC_EDIT_RESULT按键的消息响应函数中添加如下代码

unsigned int result = add(x, y);

SetDlgItemInt(IDC_EDIT_RESULT, result);

即可在IDC_EDIT_RESULT控件中将和显示出来。

4.2 动态加载动态库

DLL静态加载是由系统完成对DLL的加载和卸载,而动态加载是由编程者调用API函数进行加载和卸载,编程者可以决定DLL文件何时加载、加载哪个动态库以及何时卸载。

4.2.1 导入动态库

使用LoadLibrary()函数导入指定的动态库,代码如下所示:

HINSTANCE hinstLib;

hinstLib = LoadLibrary(_T("C:\\Win32_DLL_Test.dll"));

其中,HINSTANCE表示动态库实例的句柄,进程中的每个DLL模块都被全局唯一的32个字节的HINSTANCE句柄标识。在Win32中,HINSTANCE与HMODULE的值是相同的。LoadLibrary()函数的参数即为要导入的动态库的绝对路径。

4.2.2 在动态库中找到所需函数的地址

函数的地址即为函数的指针。函数指针是指向函数的指针,像其他指针一样,函数指针也指向某个特定的类型。函数类型由其返回类型以及形参表确定。

要获取add()函数的地址,首先要根据add()函数的返回值类型和形参表定义一个指针变量:

typedef unsigned int(*lpAddFun)(unsigned int, unsigned int);

以上代码定义了一个名为lpAddFun类型的函数指针,该函数的返回值是unsigned int,具有两个类型为unsigned int的变量。

之后,调用GetProcAddress()函数将add()函数的指针保存到lpAddFunc类型的对象中。

 

lpAddFun addFunc;

addFunc = (lpAddFun)GetProcAddress(hinstLib, "add");

其中,GetProcAddress()函数的第一个参数表示动态库的句柄,hinstLib即为在“4.2.1 导入动态库”中导入的动态库的句柄;第二个参数表示要查找的函数名;返回值为函数的地址,即函数的指针。

4.2.3 导出函数的调用

最后,根据add()函数的地址addFunc即可实现对其本身的调用。

unsigned int result = addFunc(x, y);

SetDlgItemInt(IDC_EDIT_RESULT, result);

4.3 释放动态库

在完成了动态库导出函数的调用之后,还需要释放对动态库的引用。通过ReleaseLibrary()函数实现对动态库引用的释放。

ReleaseLibrary(hinstLib);

 

使用VS2015编译和调用动态链接库dll 1. 首先建工程,选择dll,记得勾上“导出符号” 后面不用自己搞那些宏定义会省事很多。 建立工程myDll,记得勾上“导出符号” 类型选择dll 2. IDE自动生成的代码已经把整个架构弄好了,其中和项目同名的.h和.cpp文件就是我们自己写代码的地方了。我想写的dll是导出一个类,在这里我就直接在它自动生成的CmyDll类上面改了。 myDll.h myDll.cpp 在mydll.h和mydll.cpp中给类添加成员函数 //mydll.h class MYDLL_API CmyDll { public: CmyDll(void); // TODO: 在此添加您的方法。 int myFunction(int a, int b); }; //mydll.cpp int CmyDll::myFunction(int a, int b) { return a*b; } 3.编译的时候我选择了release,这里可以用默认的debug也行 在mydll.h和mydll.cpp中给类添加成员函数 最后生成解决方案后产生的mydll.lib和mydll.dll就是我们需要的二进制文件了。lib文件是编译是要用的,而dll是调用这个库的程序运行时需要的。 调用dll 1.重新建立一个工程 这回选择普通的控制台程序就行了。我建了个名为myDllCall的工程。 2.把库的头文件include进来,以及连接lib文件 其中 include进来的 myDll.h 和 **#pragma comment()**的lib根据自己的路径写。 #include "stdafx.h" #include "../../myDll/myDll/myDll.h" //头文件 #pragma comment(lib,"../../myDll/Release/myDll.lib") //调用自己写的外部库 #include int main() { CmyDll mydll; int a, b; std::cin >> a >> b; std::cout << mydll.myFunction(a, b) <> a >> b; std::cout << mydll.myFunction(a, b) << std::endl; return 0; } 3.dll放到可执行文件同一目录下面 刚刚的代码直接编译没问题,运行会报错. 直接编译没问题,运行会报错 原因是dll要和生成的可执行文件在同一个目录下,我把mydll.dll放进去之后就解决了。 我们成功的在自己的工程里调用了外部的类 可以看到我们成功的在自己的工程里调用了外部的类。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值