动态链接库在VS中的调用方法

本文详细介绍了在VisualStudio中如何通过隐式链接和显示链接两种方式调用DLL文件中的函数和数据,包括使用.lib文件、#pragmacomment指令、直接添加到解决方案视图以及LoadLibrary、GetProcAddress和FreeLibrary等API函数的使用方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

动态链接库在VS中的调用方法

应用程序要调用DLL中的函数、变量等内容,需要知道这些导出内容的地址,这个过程叫做链接。应用程序链接DLL的方式有两种:隐式(动态)链接 和 显示(动态)链接,下面逐一介绍这两种方法。

一、隐式链接

DLL项目在编译后会产生.dll文件和.lib文件,.lib文件也叫导入库文件,包含了DLL各种导出资源的链接信息,通过导入库文件来获取DLL的链接信息,就是DLL中各种导出资源实际代码的指针,通过这些指针,就可以具体执行DLL中的代码了,所以本质还是通过指针来实现的。

隐式链接使用DLL的基本流程

(1)在应用程序项目中引用导入库文件(.lib),有下面三种方法

1)在项目属性中设置; 2)使用指令 #pragma comment; 3)直接添加到解决方案视图中去。

(2)在应用程序中包含头文件
(3)在应用程序中调用DLL中的数据、函数或者类

1)在项目属性中设置
第一步:首先准备好我们在VS中DLL项目,其中头文件和源文件如下

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

第二步:在解决方案中添加一个MFC项目来调用Test.dll中的f()函数,项目名称为UseDll,在“MFC应用程序向导”的对话框中选择应用程序类型为“基于对话框”。(有些同学可能添加不了MFC项目,是因为在VS中对应的模块没有安装,需要在导航器里面添加下载一下)

在这里插入图片描述
在侧面的工具箱中拖入一个按钮在对话框中,双击按钮,跳转到下面的cpp文件中,把f()函数加入进去,再包含一下对应的Test.h头文件。
在这里插入图片描述
再配置一下对应的项目属性,分别添加 库目录的路径 和 所需要添加的库名.lib
在这里插入图片描述
在这里插入图片描述
保存好后,右击调试新示例运行该项目就可以了。
在这里插入图片描述
在这里插入图片描述

2)使用指令 #pragma comment
第一步:首先准备好我们在VS中DLL项目(同上)
第二步:同样在解决方案中添加一个对话框项目UseDll2来调用Test.dll中的f()函数,其它操作和第一种方法完全一样,就是有一步不同:第一种方法中配置项目属性的附加依赖项-输入-Test.lib 这一操作被#pragma comment(lib,"Test.lib")代替了,也就是说这一步直接写进代码里面了,不需要再手动配置了。

在这里插入图片描述

3)直接添加到解决方案视图中去(最直接最简单)
直接再文件夹中找到要导入的Test.lib文件,将其拖拽到MFC项目名称上,然后松手,再资源文件下就会多了这个文件

在这里插入图片描述

接下来只需要在UseDllDlg.Cpp中包含一下头文件Test.h即可,就可以调用成功了。

二、显式链接

显示链接不需要使用导入库文件(.lib文件),二十通过三个API函数实现动态库的调用。先通过LoadLibrary()函数来加载动态链接库,再通过GetProcAddress()来获取动态链接库导出函数的地址并执行导数函数,最后通过FreeLibrary()来卸载动态链接库。下面简要介绍一下这三个函数:

LoadLibrary()函数原型

HMODULE WINAPI LoadLibrary(LPCTSTR lpFileName);

其中参数lpFileName指向要加载的动态链接库的路径或者文件名,如果lpFileName不是路径而是一个文件名,则这个函数会通过标准的搜索策略来搜索这个文件。如果函数成功找到文件,则返回加载成功的动态链接库模块句柄,如果失败返回NULL,失败错误代码可以通过函数GetLastError()来获得。

GetProcAddress()函数原型

FARPROC GetProcAddress(HMODULE, hModule, LPCSTR lpProName);

其中参数hModule是动态链接库的模块句柄,lpProName是动态链接库中导出函数或者变量的名称,如果这个函数成功,则返回期望导出的函数或者变量的地址,否则返回NULL,失败错误代码可以通过函数GetLastError()来获得。

FreeLibrary()函数原型

BOOL FreeLibrary(HMODULE, hModule);

其中参数hModule是动态链接库的模块句柄,如果函数成功则返回非零,否则返回零。

下面通过例子来说明显示调用

同样准备好下面的项目
在这里插入图片描述
其中,Test项目是和上面类似
在这里插入图片描述
在这里插入图片描述
UseDll.Cpp中的显示链接代码如下:

// UseDll.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include "windows.h"
//定义函数指针类型
typedef int(*FUNC)(TCHAR *, int);

int _tmain(int argc, _TCHAR* argv[])
{
	HINSTANCE hDll = NULL;
	FUNC myf;//定义函数
	int res;


	hDll = LoadLibrary(_T("Test.dll"));
	if (!hDll)
	{
		puts("Test.dll加载失败");
		goto end;
	}
	myf = (FUNC)GetProcAddress(hDll, "f1");
	if (!myf)
	{
		puts("获取函数失败");
		goto end;
	}
	res = myf(_T("你好"), 10);

	printf("返回值是:%d\n", res);

	FreeLibrary(hDll);

end:
	return 0;
}

右击调试新示例运行UseDll项目就可以了。
在这里插入图片描述

使用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、付费专栏及课程。

余额充值