「C++学习笔记」动态链接库(Dll):C++动/静态调用C++的dll

接上一篇:「C++学习笔记」动态链接库(Dll):创建与调试

因为本文中对用到的C++ dll的详细情况没有细说,全部在上一篇文章中。

所以建议先去速览一下,以便看本文的时候不至于懵逼。

写好的dll如何调用呢,使用C++调用动态链接库时有两种方式:静态和动态

1、C++静态方式调用dll

这种方式基本和上一篇中dll的调试性质一样,好处是你可以使用dll中的原函数名,在代码上比动态调用要好看的多。

1.1、先建个项目再说

在dll的解决方案目录下创建一个控制台项目:“CppUseDllStatic”

创建在同一个目录下是为了代码管理方便,你也可以在其他地方创建。

1.2 静态调用的配置

静态调用的方式需要三个主要文件,

1:dll项目中声明所有暴露函数的头文件(例如我之前建好的项目中的“CppDllDemo.h”),

2:“xxx.dll”文件,即动态链接库(如我的是“CppDllDemo.dll”),

3:“xxx.lib”文件,与“.dll”同时生成的,且在同一目录下(如 我的是“CppDllDemo.lib”)

 打开项目属性,把头文件所在路径复制到【VC++目录】→【包含目录】中。

(这样做是为了在#include时直接写头文件名,如果你不嫌麻烦,直接include该头文件的全路径名也行,又或者把这个头文件复制到该项目的根目录下再include也行,随你)

在上图的库目录中,加入“xxx.lib”文件所在的目录,然后在【链接器】→【输入】→【附加依赖项】中加入lib文件名:“xxx.lib”

如果你觉得加入库目录、添加附加依赖项很麻烦,你也可以在代码中,用如下代码代替:

#pragma comment(lib, "D:\\code\\CppDllDemo\\x64\\Debug\\CppDllDemo.lib")

接着就是把“xxx.dll”文件放到控制台程序生成的“xx.exe”文件所在目录。 

1.3 完成以上,就可以在代码中进行调用了

调用的示例代码如下:

#include <iostream>
#include <CppDllDemo.h> //如果没有“包含目录”,就写全路径吧:D:\\balabalabala\\CppDllDemo.h

//如果没有加“库目录”和“附加依赖项”,就使用下面这句吧
//#pragma comment(lib, "D:\\code\\CppDllDemo\\x64\\Debug\\CppDllDemo.lib")

using namespace std;

int main()
{
	double result = Add(4.5, 11.2);
	cout << "result = " << result << endl;
	SayHello();
	cin.get();
}

 有用过opencv的同学一定觉得很眼熟:「图像处理」OpenCV的安装与配置

opencv的配置,就是静态方式加载dll的方式。

2、动态方式调用dll

协同开发的很多时候,都只有dll文件而没有“.h”和“.lib”文件,而且很多时候,dll的开发人员并不愿意提供这两个文件,再者,用久了就会发现,很多小的dll,动态调用方式是要比静态方便的多的。

如何以动态的方式调用呢,只要有“xxx.dll”文件………………和“接口说明文档”(谁开发的找谁要)

之所以要文档,是你必须知道dll中的函数有哪些,每个函数的名称和参数类型是什么。

接下来直接上代码:

#include <iostream>
#include <Windows.h> //新版本里面,要包含下面的头文件就必须要Windows.h
#include <libloaderapi.h> //需要用到下文中的LoadLibrary()

using namespace std;

//导入动态库  
//使用了unicode字符集,LoadLibrary 是LoadLibraryW(LPCWSTR lpLibFileName),需要注意参数类型转换
HMODULE DllHolder = LoadLibrary(L"D:\\code\\CppDllDemo\\x64\\Debug\\CppDllDemo.dll");

//定义与dll中Add函数相同的函数指针类型,dll中Add函数的参数类型是(double, double)
typedef double(_stdcall* pAdd)(double, double);
//在dll中按“Add”名称找到函数并赋值给pAdd的实例函数指针(你可以随意起名)
pAdd AddFunc = (pAdd)GetProcAddress(DllHolder, "Add");

//下面两行参考上面的注释吧
typedef void(_stdcall* pSayHello)();  //dll中SayHello函数没有入参
pSayHello SayHelloFunc = (pSayHello)GetProcAddress(DllHolder, "SayHello");

int main()
{
	double result = AddFunc(4.5, 11.2);
                    //也可以这样使用:(*AddFunc)(4.5, 11.2)
	cout << "result = " << result << endl;
	SayHelloFunc();
	cin.get();
}

以上就是C++调用C++ dll的动态与静态方式,贴一张运行成功的截图以做纪念:

3、最重要的一点

我们调用dll进行编译和最终交付使用(运行编译生成的exe)是两回事,是两个环境。

所以,在静态调用时,不管你在编译时怎么配置,最终的exe运行的时候所调用的dll都是从其自身所在目录下开始找“xxx.dll”文件,所以你写好程序后,要记得吧用到的dll都复制到你生成的exe文件同目录中去。

对于动态调用,代码中会显式指定“xxx.dll”的路径,指要路径正确,就可以了。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值