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);

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值