VC++ 动态库(dll)、静态库(lib)

创建一个静态库项目

如下图所示,创建一个 C++ 静态库项目

在这里插入图片描述

创建完后,项目的目录如下所示

在这里插入图片描述

其中的 StaticLib1.cpp 文件是我创建的,并不是初始内容。StaticLib1.cpp 文件的内容如下所示:

// StaticLib1.cpp : 定义静态库的函数。
//

#include "pch.h"
#include "framework.h"
#include<iostream>

using namespace std;

// TODO: 这是一个库函数示例
void Print(void)
{
	cout << "hello world" << endl;
}

然后就可以生成项目了,如下图所示
在这里插入图片描述
选择“生成StaticLib1”选项。

然后在 repos/[解决方案名称]/x64/Debug 文件夹中,就会生成如下所示的文件
在这里插入图片描述
其中的 lib 文件就是我们要的静态链接库。

创建动态链接库项目

如下图所示,创建动态链接库项目
在这里插入图片描述
项目结构如下图所示
在这里插入图片描述
其中 Math.hMath.cpp 这两个文件是我添加的,不是本来有的。

Math.h 的内容如下所示

#pragma once

#ifdef DLL1_EXPORTS
	#define API __declspec(dllexport)
#else
	#define API __declspec(dllimport)
#endif // DLL1_EXPORTS

namespace myLib
{
	class API Math
	{
	public:
		static int Add(int a, int b);
	};
}

Math.cpp 的内容如下

#include "pch.h"
#include "Math.h"

namespace myLib
{
	int Math::Add(int a, int b)
	{
		return a + b;
	}
}

Math.h 文件中,有如下宏定义

#ifdef DLL1_EXPORTS
	#define API __declspec(dllexport)
#else
	#define API __declspec(dllimport)
#endif // DLL1_EXPORTS

其中,DLL1_EXPORTS是VS自动帮我们加的宏定义。在创建 C++ 动态库项目后,VS 会帮我们加上一个宏定义,这个宏定义的格式为 [项目名称转为大写字母]_EXPORTS,例如这里的项目名称为Dll1,则 VS 帮我们加上了宏定义DLL1_EXPORTS

看下图,可以发现DLL1_EXPORTS宏的颜色是亮起的,说明 VS 确实帮我们加了 DLL1_EXPORTS 宏。
在这里插入图片描述

使用__declspec(dllexport)关键字可以导出想要导出的内容。这里导出了 Math 类。

关于这部分内容,可以参考MSDN

然后就可以点击生成了。如下图所示
在这里插入图片描述
生成后输出文件夹变成
在这里插入图片描述
Dll1.dll文件就是我们想要的动态链接库。但是,可以发现还多了一个 Dll1.lib。lib 文件不是静态链接库嘛,为什么会出现这个?

其实C++的动态链接库并不是孤零零的一个 dll,总是有一个伴生的 lib 文件,这个 lib 文件用来当做中介,使 dll 的使用者能够正确地调用 dll 中的内容。

与静态链接库中的 lib 不同,动态链接库中的 lib 不包含我们想要的导出内容,仅仅是作为中介而已。调用方如果在链接时链接了这个 lib 文件,然后我们不提供 dll 文件,它是无法运行的。而静态链接库的 lib 文件包含了完整的内容,不需要提供 dll 文件也能被调用方正常使用。

使用静态库、动态库

说了这么多,终于到了使用环节了。

创建一个 C++ 控制台项目,如下图所示
在这里插入图片描述

将下图所示的高亮的两个文件复制到控制台项目的“资源文件”文件夹中
在这里插入图片描述
结果如下所示
在这里插入图片描述

它们的 dll 文件不需要复制。因为等会控制台项目的生成文件也会输出到这个输出文件夹中,即控制台项目生成的 exe 文件会与所需的 dll 文件处于同一个文件夹中。

接下来编辑控制台项目的源文件

#include <iostream>
/*下面使用了相对路径来找到 Dll1 项目中的 Math.h 文件。因为标准库中
有一个 math.h 所以如果将 Math.h 复制到控制台项目的“头文件”文件夹中,
然后直接

#include"Math.h"

会报错,使用相对路径

#include"./Math.h"

也会报错,编译器都以为是要找标准库的 math.h
*/
#include "../Dll1/Math.h"

void Print(void);

int main()
{
    Print();
    std::cout << myLib::Math::Add(665, 1) << std::endl;
    getchar();
    getchar();
    return 0;
}

这里声明了 Print 函数,因为刚才创建的静态库并没有头文件。所以我们想要使用那个静态库,就要自己声明要使用的函数。真正的生产环境中,将静态库给别人时可千万别这么干。直接给别人一个 lib 文件,不给头文件。


然后就可以生成了
在这里插入图片描述

点击运行按钮
在这里插入图片描述
运行结果如下
在这里插入图片描述

验证动态库只有 lib 不行

接下来验证动态库只有 lib 文件,没有 dll 文件不行。


将可执行文件复制到一个别处的空文件夹中。结果如下
在这里插入图片描述

在终端中打开此文件夹,用命令行运行,如下图所示
在这里插入图片描述
结果什么都没有。exe 根本无法正常运行。


然后将动态库的 dll 文件复制过来,如下图所示
在这里插入图片描述

再次用命令行运行,结果如下

在这里插入图片描述

这次成功运行了。


所以动态库只有 lib 文件是不行的。即使在链接时链接了 lib 文件,在运行时仍然需要动态链接 dll 文件。

使用项目引用保持依赖项为最新

刚才是通过将 lib 文件复制到控制台项目的“资源文件”文件夹中来让控制台项目能够引用动态库、静态库。这种方式有个问题,就是当我们更新库的时候,还要重新复制 lib 文件到控制台项目的“资源文件”文件夹中。这很麻烦。更方便的方法就是添加项目引用。

右键点击控制台项目的“引用”
在这里插入图片描述
出来如下所示的菜单
在这里插入图片描述
选择“添加引用”。然后如下图所示,将本解决方案中的依赖项目勾上
在这里插入图片描述
然后就可以删除“资源文件”文件夹中的内容了
在这里插入图片描述
点击生成。生成的输出信息如下

已启动重新生成...
1>正在生成代码...
1>  正在创建库 C:\Users\huang\source\repos\MAUI_Learn\x64\Debug\Dll1.lib 和对象 C:\Users\huang\source\repos\MAUI_Learn\x64\Debug\Dll1.exp
1>Dll1.vcxproj -> C:\Users\huang\source\repos\MAUI_Learn\x64\Debug\Dll1.dll
2>StaticLib1.vcxproj -> C:\Users\huang\source\repos\MAUI_Learn\x64\Debug\StaticLib1.lib
3>------ 已启动全部重新生成: 项目: ConsoleApplication1, 配置: Debug x64 ------
3>ConsoleApplication1.cpp
3>ConsoleApplication1.vcxproj -> C:\Users\huang\source\repos\MAUI_Learn\x64\Debug\ConsoleApplication1.exe
========== “全部重新生成”: 3 成功,0 失败,0已跳过 ==========
========== 占用时间 00:04.069 ==========

可以看到,在生成控制台项目的时候,会自动连它依赖的项目一起生成,这样可以始终保持最新状态。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值