静态库与动态库的制作与使用


前言

当我们开发一个较大规模的程序时,将代码拆分为多个模块可提高可维护性和代码重用性。在C++中,我们可以通过创建和使用静态库和动态库来实现这一点。在本篇博客中,我将为你介绍如何创建和使用静态库和动态库。

一、动态库与静态库

1、静态库以及优缺点

静态库:在编译时与程序代码直接链接,生成的可执行文件包含了库中所有需要的代码。因此,可执行文件较大,但不需要额外的库文件。静态库:通常以 .lib(Windows)或 .a(Linux/UNIX)为扩展名。
静态库的优点:
简单易用:静态库是一组已编译好的目标文件的集合,使用起来非常简单方便,只需链接到应用程序中即可。
独立性:静态库包含了其所需的所有代码和依赖项,使得应用程序在不同的环境中也能独立运行,不受外部环境的影响。
性能优势:静态库在编译时被完整地链接到应用程序中,可以在编译期间进行优化,减少了运行时的开销,因此通常具有更好的性能。
静态库的缺点:
冗余:由于静态库将其所有代码和依赖项都链接到应用程序中,可能会导致应用程序的体积较大,占用较多的存储空间。
更新麻烦:如果静态库更新了,需要重新编译并重新链接整个应用程序,这可能会增加维护的复杂性。
版本问题:如果应用程序使用的是不同版本的静态库,可能会导致冲突和兼容性问题。在这种情况下,需要小心管理库的版本,并确保正确链接适当的版本。

2、动态库以及优缺点

动态库:在编译时不直接链接到程序中,而是在程序运行时动态链接。生成的可执行文件不包含库中的代码,只包含对库的引用。因此,可执行文件较小,但需要库文件才能运行。动态库:通常以 .dll(Windows)或 .so(Linux/UNIX)为扩展名。
优点:
代码重用:动态库允许多个程序共享相同的代码,有助于减少冗余和提高维护性。
内存占用:由于多个程序可以共享同一动态库的内存实例,因此可以减少内存占用。
更新简便:对动态库的更新不需要重新编译使用它的程序,只需要替换动态库文件即可。这可以降低更新和维护成本。
缺点:
代码重用:动态库允许多个程序共享相同的代码,有助于减少冗余和提高维护性。
内存占用:由于多个程序可以共享同一动态库的内存实例,因此可以减少内存占用。
更新简便:对动态库的更新不需要重新编译使用它的程序,只需要替换动态库文件即可。这可以降低更新和维护成本。

二、静态库的制作与使用

创建静态库

静态库是编译后的目标文件的集合,可以被链接到应用程序中。下面是创建静态库的步骤:

  1. 编写源代码文件并编译为目标文件(.o):首先,你需要编写你的源代码文件,然后使用编译器将其编译为目标文件。例如,假设有两个源代码文件 math.cppstring.cpp

    // math.cpp
    int add(int a, int b) {
        return a + b;
    }
    
    // string.cpp
    #include <string>
    std::string concatenate(const std::string& str1, const std::string& str2) {
        return str1 + str2;
    }
    

    使用以下命令分别将这两个源文件编译为目标文件:

    g++ -c math.cpp -o math.o
    g++ -c string.cpp -o string.o
    
  2. 将目标文件打包为静态库(.a):使用 ar 命令将目标文件打包为静态库。例如,将上一步生成的两个目标文件打包为静态库 libmylib.a

    ar rcs libmylib.a math.o string.o
    

    此命令将创建名为 libmylib.a 的静态库。

使用静态库

一旦创建了静态库,我们可以在应用程序中使用它。以下是使用静态库的步骤:

  1. 编写应用程序源代码:编写一个应用程序的源代码文件,使用静态库中提供的函数或类等。例如,假设有一个应用程序文件 main.cpp

    #include <iostream>
    #include "math.h"
    
    int main() {
        int result = add(3, 4);
        std::cout << "Result: " << result << std::endl;
        return 0;
    }
    
  2. 编译应用程序并链接静态库:使用编译器编译应用程序源代码,并将静态库链接到应用程序中。例如,使用以下命令编译 main.cpp 并链接 libmylib.a 静态库:

    g++ main.cpp -o main -L. -lmylib
    

    此命令将生成可执行文件 main

    • -L.:指定静态库所在的目录(当前目录)。
    • -lmylib:指定要链接的静态库的名称(去掉 lib 前缀和 .a 后缀)。
  3. 运行应用程序:运行生成的可执行文件。

    ./main
    

    应该会看到输出的结果为 Result: 7

三、动态库的制作与使用

创建动态库

与静态库不同,动态库在运行时被加载。下面是创建动态库的步骤:

  1. 编写源代码文件并编译为目标文件(.o):与创建静态库相同,你需要将源代码文件编译为目标文件。

  2. 将目标文件编译为共享对象(.so):使用以下命令将目标文件编译为动态库:

    g++ -shared -o libmylib.so math.o string.o
    

    此命令将创建名为 libmylib.so 的动态库。

使用动态库

使用动态库与使用静态库类似,以下是使用动态库的步骤:

  1. 编写应用程序源代码:编写一个应用程序的源代码文件,使用动态库中提供的函数或类等。

  2. 编译应用程序并链接动态库:与使用静态库相比,编译和链接的命令稍有不同:

    g++ main.cpp -o main -L. -lmylib
    

    其中,-lmylib 指定要链接的动态库名称,而编译器会根据系统配置自动查找和加载动态库。

  3. 运行应用程序:运行生成的可执行文件。

    ./main
    

    你应该能够看到与静态库相同的输出结果。

四、cmake编写静态库与动态库

cmake_minimum_required(VERSION 3.12)
project(MyProject)

# 添加源代码文件
add_executable(MyApp main.cpp)

# 添加静态库
add_library(MyLib STATIC math.cpp string.cpp)

# 添加动态库
add_library(MyLib SHARED math.cpp string.cpp)

# 链接静态库到应用程序
target_link_libraries(MyApp PRIVATE MyLib)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值