静态库的制作和使用
什么是库
在C++中,库(library)是一组预先编译的代码,这些代码可以在多个程序中重用,而无需重复编写相同的代码。C++库可以大致分为两类:标准库和第三方库。
-
标准库:C++标准库提供了大量的常用功能,比如数据结构(如向量、列表、映射等)、算法(如排序和搜索)、以及用于输入输出的功能等。这些都是C++标准的一部分,任何遵循标准的C++编译器都会提供这些库。例如,iostream库用于输入输出操作,vector库用于操作动态数组等。
-
第三方库:除了标准库之外,还有许多由第三方开发的库,这些库提供了额外的功能,比如图形界面、网络通信、数学运算等。这些库需要单独下载和安装,不同的库可能有不同的配置方式。一些知名的第三方库包括Boost库、Qt(用于图形界面)、OpenCV(用于计算机视觉)等。
库通常以两种形式存在:
- 头文件(Header files):包含了库中函数的声明和数据类型的定义。这些文件以.h或.hpp为扩展名。
- 编译后的代码:可以是静态库(.lib或.a文件)或动态链接库(.dll或.so文件)。静态库在程序编译时被整合到程序中,动态链接库则在程序运行时被加载。
使用库可以大大加快开发速度,提高代码的可重用性和可维护性。
静态库和动态库是C++中两种常见的库类型,它们在程序构建和运行时的行为和用途上有着明显的区别:
静态库
- 定义:静态库是在程序编译链接时被整合到最终的可执行文件中的一组函数和数据的集合。
- 文件类型:在Windows系统中,静态库的文件通常有
.lib
扩展名,在Unix-like系统中,通常是.a
(archive)扩展名。 - 使用时机:静态库在编译链接阶段就被整合到程序中,最终的可执行文件包含了静态库的所有代码。
- 优点:
- 自包含:生成的可执行文件包含所有必需代码,不依赖外部库文件,便于分发。
- 执行速度:调用库函数时,不需要额外的加载或链接过程,可能会有更好的性能。
- 缺点:
- 文件大小:可执行文件体积较大,因为包含了整个库的代码。
- 更新困难:如果库更新,整个应用需要重新编译和分发。
动态库
- 定义:动态库是在程序运行时被加载的一组函数和数据的集合。
- 文件类型:在Windows系统中,动态库的文件通常是
.dll
(Dynamic Link Library)扩展名,在Unix-like系统中,通常是.so
(Shared Object)扩展名。 - 使用时机:动态库在程序运行时被加载到内存中,多个程序可以共享同一个库文件的单个副本。
- 优点:
- 节省内存和磁盘空间:多个程序可以共享同一个库副本,减少重复数据的存储。
- 易于更新:更新库文件后,不需要重新编译使用该库的程序,只需替换库文件即可。
- 缺点:
- 依赖性:程序运行依赖外部库文件,缺失或不兼容的库文件可能导致程序无法运行。
- 运行时开销:加载库可能增加程序启动时间,且运行时链接可能引入额外开销。
总结来说,静态库和动态库各有利弊,适用于不同的场景。在选择库类型时,应根据应用的具体需求和部署环境来决定使用哪种类型的库。
静态库的制作
-
编写源代码:
创建你的函数和数据结构的源文件(例如file1.cpp
和file2.cpp
)。 -
编译源代码为目标文件:
使用GCC编译器将每个源文件编译成目标文件(.o
文件)。g++ -c file1.cpp -o file1.o g++ -c file2.cpp -o file2.o
-
创建静态库:
使用ar
工具将目标文件打包成一个静态库文件(.a
文件)。这个工具用于创建、修改和从存档库中提取文件。ar rcs libmystatic.a file1.o file2.o
其中
rcs
是ar
命令的选项:r
: 插入文件(如果库已存在,则替换)。c
: 创建库文件,如果不存在。s
: 创建索引到库中,加速链接过程。
-
链接静态库:
当你创建可执行文件时,链接这个静态库。g++ -o myprogram main.cpp libmystatic.a
daic@daic:~/Linux/lesson04/calc$ tree
.
├── add.c
├── div.c
├── head.h
├── main.c
├── mult.c
└── sub.c
0 directories, 6 files
daic@daic:~/Linux/lesson04/calc$ gcc -c add.c div.c mult.c sub.c
daic@daic:~/Linux/lesson04/calc$ ls
add.c add.o div.c div.o head.h main.c mult.c mult.o sub.c sub.o
daic@daic:~/Linux/lesson04/calc$ tree
.
├── add.c
├── add.o
├── div.c
├── div.o
├── head.h
├── main.c
├── mult.c
├── mult.o
├── sub.c
└── sub.o
0 directories, 10 files
daic@daic:~/Linux/lesson04/calc$
daic@daic:~/Linux/lesson04/calc$ ar rcs libcalc.a *.o
daic@daic:~/Linux/lesson04/calc$ tree
.
├── add.c
├── add.o
├── div.c
├── div.o
├── head.h
├── libcalc.a
├── main.c
├── mult.c
├── mult.o
├── sub.c
└── sub.o
0 directories, 11 files
静态库的使用
使用静态库主要涉及到几个步骤:将库包含到你的项目中,配置项目以使用库,然后在代码中引用库提供的功能。以下是在不同开发环境中使用静态库的基本步骤。
在Unix-like系统中使用GCC
-
引入头文件:
在你的源代码中,包含静态库提供的头文件。这样你就可以使用库中定义的函数、类和数据结构。#include "mylibrary.h"
-
编译程序:
在编译程序时,需要链接静态库。这通常通过指定库文件的路径来完成。g++ -o myprogram main.cpp path/to/libmystatic.a
如果库文件与源代码不在同一目录下,你可能还需要指定库的搜索路径:
g++ -o myprogram main.cpp -L/path/to/library -lmystatic
其中
-L
选项用于指定库的目录,-l
(注意是小写的L)后面跟上库的名称,不包括前缀lib
和文件扩展名.a
。 -
运行程序:
编译和链接完成后,你可以直接运行生成的可执行文件。由于静态库的内容已经包含在内,因此不需要额外的运行时配置。
静态库制作和使用整体流程
daic@daic:~/Linux/lesson05/library$ tree
.
├── include
│ └── head.h
├── lib
├── main.c
└── src
├── add.c
├── div.c
├── mult.c
└── sub.c
3 directories, 6 files
daic@daic:~/Linux/lesson05/library$ gcc -c ./src/*.c
./src/sub.c:2:10: fatal error: head.h: No such file or directory
#include "head.h"
^~~~~~~~
compilation terminated.
daic@daic:~/Linux/lesson05/library$ gcc -c ./src/*.c -I ./include/
daic@daic:~/Linux/lesson05/library$ tree
.
├── add.o
├── div.o
├── include
│ └── head.h
├── lib
├── main.c
├── mult.o
├── src
│ ├── add.c
│ ├── div.c
│ ├── mult.c
│ └── sub.c
└── sub.o
3 directories, 10 files
daic@daic:~/Linux/lesson05/library$ ar rcs *.o libcalc.a
ar: add.o: File format not recognized
daic@daic:~/Linux/lesson05/library$ ar rcs libcalc.a *.o
daic@daic:~/Linux/lesson05/library$ tree
.
├── add.o
├── div.o
├── include
│ └── head.h
├── lib
├── libcalc.a
├── main.c
├── mult.o
├── src
│ ├── add.c
│ ├── div.c
│ ├── mult.c
│ └── sub.c
└── sub.o
3 directories, 11 files
daic@daic:~/Linux/lesson05/library$ rm *.o
daic@daic:~/Linux/lesson05/library$ mv libcalc.a ./lib
daic@daic:~/Linux/lesson05/library$ ls
include lib main.c src
daic@daic:~/Linux/lesson05/library$ gcc main.c -o app
main.c:2:10: fatal error: head.h: No such file or directory
#include "head.h"
^~~~~~~~
compilation terminated.
daic@daic:~/Linux/lesson05/library$ gcc main.c -I ./include/
/tmp/ccC1e9j5.o: In function `main':
main.c:(.text+0x3a): undefined reference to `add'
main.c:(.text+0x5c): undefined reference to `subtract'
main.c:(.text+0x7e): undefined reference to `multiply'
main.c:(.text+0xa0): undefined reference to `divide'
collect2: error: ld returned 1 exit status
daic@daic:~/Linux/lesson05/library$ gcc main.c -I ./include/ -L ./lib -l calc
daic@daic:~/Linux/lesson05/library$ ls
a.out include lib main.c src
daic@daic:~/Linux/lesson05/library$ gcc main.c -I ./include/ -L ./lib -l calc -o app
daic@daic:~/Linux/lesson05/library$ ls
a.out app include lib main.c src
daic@daic:~/Linux/lesson05/library$ ./app
a = 20, b = 12
a + b = 32
a - b = 8
a * b = 240
a / b = 1.666667
原文地址:https://blog.csdn.net/qq_36372352/article/details/137911615
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!