【C++】静态库与动态库开发(上)-静态库

本文详细介绍了程序执行的基本流程,包括源代码编写、编译、链接、加载、执行等步骤,重点讲解了静态库和动态库的概念、优缺点以及在VisualStudio2019中创建和使用静态库的实例。
摘要由CSDN通过智能技术生成

首先,我们需要了解一下程序执行的流程主要分为以下几个主要步骤:

  1. 源代码编写:编写源代码,并使用合适的编程语言编写算法、逻辑和功能实现。

  2. 编译:源代码通过编译器转换为目标代码。编译器将源代码翻译成计算机可以理解的机器语言,生成目标文件(通常是机器代码或字节码),其中包含了可执行程序的二进制表示。

  3. 链接:在编译过程中,程序可能会依赖于其他源代码文件或库文件。链接器将目标文件及其依赖项组合在一起,解决符号引用,并生成最终的可执行文件。在静态链接中,所有依赖项都被包含在最终的可执行文件中。在动态链接中,依赖项以动态链接库的形式存在,可在运行时加载。

  4. 加载:操作系统加载可执行文件到内存中,并将程序的控制权交给其入口点(通常是 main 函数)。

  5. 执行:程序开始执行,按照源代码中的逻辑进行计算和操作。在执行过程中,程序可能会读取输入、处理数据、调用函数、输出结果等。

  6. 结束:程序执行完毕后,操作系统释放程序所占用的资源,并返回控制权给操作系统。程序执行的结果可能会被输出到终端或存储在文件中。

这些步骤构成了程序的整个执行过程,从源代码的编写到最终的执行和结果输出。

链接的过程中我们提到了“库”这个概念,在计算机科学中,库(Library)是指一组已经编译好的代码和数据,它们可以在程序中被重复使用。库通常包含了一组函数、类、数据结构或其他可执行代码的集合,以及相应的文档和头文件等。

库可以分为两种主要类型:

  1. 静态库(Static Library):静态库是一组已经编译好的代码和数据,它们在链接时被嵌入到最终的可执行文件中。这意味着在使用静态库的程序中,这些库的代码会被复制到最终的可执行文件中,因此可执行文件可以独立地运行,不需要依赖外部的库文件。静态库的文件通常具有 .lib(Windows)或 .a(Unix/Linux)的扩展名。

  2. 动态库(Dynamic Library):动态库是一组已经编译好的代码和数据,它们在程序运行时被动态加载到内存中。这意味着在使用动态库的程序中,它们不会被复制到可执行文件中,而是在程序运行时由操作系统加载到内存中供程序调用。动态库的文件通常具有 .dll(Windows)或 .so(Unix/Linux)的扩展名。

使用库的主要优点包括:

  • 代码重用:库中的函数和数据结构可以在多个程序中被重复使用,从而节省开发时间和代码量。
  • 模块化开发:库可以帮助将代码模块化,提高代码的可维护性和可重用性。
  • 性能优化:使用库可以提高程序的性能和效率,因为库中的函数通常经过优化和测试。
  • 标准化接口:库提供了标准化的接口和功能,可以方便地在不同的程序中使用。

表1为动态库和静态库的特性比较:

表1 静态库与动态库特性比较
特性静态库动态库
独立性可执行文件包含所有依赖的代码和数据,独立运行需要运行时加载依赖的库文件,可能依赖于外部库的存在
可移植性可执行文件可在没有安装相应库的系统上运行可执行文件依赖于外部库的存在,需要确保库文件在运行时可用
性能编译时将库的代码复制到可执行文件中,无需运行时加载运行时动态加载库文件,可能会带来一些额外的性能开销
更新和维护静态库更新需要重新编译和重新链接可执行文件动态库更新只需要替换库文件,无需重新编译可执行文件
文件大小可执行文件较大,包含了所有依赖的库的副本可执行文件较小,不包含库的副本,依赖于外部库文件
共享性每个可执行文件包含一份库的副本,资源浪费多个可执行文件可以共享同一个库,节省磁盘空间和内存
动态加载和卸载不支持动态加载和卸载库支持动态加载和卸载库,提高程序的灵活性和可扩展性
安全性静态链接的库代码不易受到恶意程序的篡改动态加载的库文件可能受到恶意程序的替换,存在一定的安全风险

        visual studio 2019环境下静态库的创建和使用示例:

        首先创建新项目,选择项目模板为“静态库”。

图1

                 下一步填写项目名称,这里命名为“testlib”,手动选择项目保存的位置。

图2

        点击创建之后进入到vs2019的编译界面,在右侧的“解决方案资源管理器”目录下,我们可以看到vs2019已经给我们创建好了几个默认的文件了,分别是“framework.h”、“pch.h”、“pch.cpp”、“testlib.cpp”。其中的“framework.h”、“pch.h”、“pch.cpp”分别是预编译头文件及其对应的源文件,点进去这些文件中可以发现并不存在什么实际内容,预编译头是一种优化编译速度的机制,它会将常用的头文件预先编译成二进制文件,然后在编译过程中重复使用,从而加快编译速度。但是对于编写的比较小的程序来说,这点速度的提高可能根本感觉不出来,同时也不建议大家删除,删除可能会报错,我们直接忽略不用就行,因此直接忽略“framework.h”、“pch.h”、“pch.cpp”这三个文件就行了,其余的代码还是该怎么写就怎么写。

图3

 我们在头文件中添加一个“testlib.h”,里面可以写上一些测试函数的声明,我这边分别写了两个函数,分别是加法运算和减法运算的函数声明。

图4

         “testlib.h”中详细代码如下:

#pragma once

//加法运算
int add(int a, int b);

//减法运算
int sub(int a, int b);

         同时,我们在“testlib.cpp”中包含“testlib.h”头文件并写上测试函数的具体定义,具体代码如下所示:

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

#include "pch.h"
#include "framework.h"
#include "testlib.h"

//加法运算
int add(int a, int b)
{
	return a + b;
}

//减法运算
int sub(int a, int b)
{
	return a - b;
}

 函数编写完成后这里不能像编译普通程序一样点击“本地windows调试器”或者按“ctrl+F5”执行程序,会产生如下报错,因为静态库是无法独立运行的。

图5

        由于我们需要将静态库发布出去供其他程序使用,因此切换至Release模式,并在右侧找到我们的静态库项目“testlib”,右键后点击“生成”来生成我们所需要的静态库。

图6

        静态库生成成功之后就可以在项目文件下的Release目录下看到“testlib.lib”静态库了。

图7

        经过以上操作我们已经成功创建了一个静态库,接下来我们创建一个控制台应用来使用前面创建好的静态库。

图8

         还是一样,给项目命名并选择项目存放的位置。

图9

        项目创建完毕后,需要准备一个第三方库的文件,新建一个文件夹,命名为“testdll”,同时在该文件夹内分别新建“include”、“bin”、“lib”这三个文件夹(一般标准是这样),分别存放头文件、二进制文件和静态库,这时候将前面生成静态库文件“testlib.lib”放入lib文件夹,“testlib.h”放入include文件夹,bin文件夹置空即可。

图10

图11 

        第三方库已经准备完毕,将这个文件夹(testlib)拖入我们创建的控制台项目“uselib”所在的同级目录。

图12

        回到编译器,需要在编译器中对添加的静态库进行配置。第一步操作如下:右击“usedll”项目,点击“属性”,选择“C/C++”栏,对其中的“附加包含目录进行修改”,附加包含目录就是.h文件(testdll.h)所在的位置(即testdll的include目录中),编辑testdll.h的相对路径,这里的相对路径的参照位置是当前的工作目录(当前的工作目录打开方式见图14,添加目录../testlib/include),使用相对路径是为了避免在不同的环境下重复配置。

图13

 图14 当前工作目录打开方式

        第二步:选择链接器栏目,在附加库目录中添加静态库的位置,也是相对路径,此处为../testlib/lib。

图15

        第三步,添加依赖项,在链接器栏下找到“输入”,添加静态库名“testlib.lib”,至此前期的工作准备完毕。

图16 

         回到编译器,在uselib.cpp中对静态库内函数做一个简单调用,代码如下:

#include <iostream>
#include "testlib.h"
using namespace std;
int main()
{
    int a, b, c;
    a = 10;
    b = 20;
    c = add(a, b);
    cout << "c: " << c << endl;

}

        执行程序,运行结果如下,静态库调用成功。

 图17

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值