Linux下Gcc生成和使用静态库和动态库详解

### Linux下Gcc生成和使用静态库和动态库详解 #### 一、基本概念 **1.1 什么是库** 库本质上是一种可执行代码的二进制形式,它可以被操作系统载入内存执行。无论是Windows还是Linux平台,都广泛地使用着库。然而,由于平台差异(特别是编译器、汇编器和连接器的不同),不同平台之间的库二进制文件并不兼容。本文主要关注Linux下的库。 **1.2 库的种类** Linux下的库主要分为两种类型:静态库和共享库(动态库)。这两种类型的库的主要区别在于代码被载入的时间点不同。 - **静态库**:在编译阶段,静态库中的代码就被直接链接到了可执行程序中。这意味着最终的可执行文件体积较大,因为它包含了所有所需的库代码。 - **动态库**(共享库):动态库的代码则是在程序运行时才被载入内存。在编译过程中,仅仅是对这些库进行引用而非实际的代码复制。这使得可执行文件体积较小,并且多个程序可以共享同一个库实例,从而节省内存空间。 **1.3 库存在的意义** 库是已经编写好并经过验证的代码集合,它们可以被重复利用。在开发过程中,几乎所有的程序都会依赖于一系列的基础库,这些库提供了许多常用的功能,从而避免了从头开始编写代码。此外,使用库还可以确保代码的质量和效率,因为这些库通常经过了广泛的测试和优化。 **1.4 库文件的产生方式** 在Linux环境下,静态库和动态库的产生方式有所不同: - **静态库**: 静态库的文件扩展名为`.a`。它的生成过程分为两个步骤: - 第一步,使用GCC编译器将源代码编译成多个`.o`文件,每个`.o`文件都包含了对应的符号表。 - 第二步,使用`ar`命令将这些`.o`文件打包成一个静态库文件。 - **动态库**: 动态库的文件扩展名为`.so`。它可以通过GCC编译器加上特定的参数直接生成。 **1.5 库文件的命名规范** 在Linux系统中,库文件通常存储在`/usr/lib`或`/lib`目录下,并遵循一定的命名规则: - **静态库**:通常命名为`libXXXX.a`,其中`XXXX`代表库的名称。 - **动态库**:通常命名为`libXXXX.so.MAJOR.MINOR`,其中`XXXX`是库的名称,`MAJOR`是主版本号,`MINOR`是次版本号。 **1.6 查看可执行程序依赖的库** 使用`ldd`命令可以查看一个可执行程序所依赖的共享库。例如: ``` # ldd /bin/ln libc.so.6 => /lib/libc.so.6 (0x0040021000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x0040000000) ``` 这表明`ln`命令依赖于`libc`库和`ld-linux`库。 **1.7 可执行程序如何定位共享库文件** 当系统加载可执行程序时,它能够知道所依赖的库的名字,但仍需确定库的绝对路径。这一过程由系统动态链接器完成。对于ELF格式的可执行程序,是由`ld-linux.so`实现的。具体流程包括: 1. 检查ELF文件的`DT_RPATH`段。 2. 检查环境变量`LD_LIBRARY_PATH`。 3. 检查`/etc/ld.so.cache`文件中的路径列表。 4. 如果上述步骤都无法找到库文件,则检查`/lib/`和`/usr/lib/`目录。 例如,可以通过设置`LD_LIBRARY_PATH`环境变量来添加自定义的共享库目录: ``` export LD_LIBRARY_PATH='pwd' ``` **1.8 如何使系统识别新安装的库** 如果库文件安装在`/lib`或`/usr/lib`目录下,通常无需额外的操作即可被系统识别。但如果库文件安装在其他目录,需要进行以下步骤: 1. 编辑`/etc/ld.so.conf`文件,添加库文件所在的目录路径。 2. 运行`ldconfig`命令更新`/etc/ld.so.cache`文件。 #### 二、使用GCC生成静态库和动态库的示例 接下来,我们将通过一个具体的示例来演示如何在Linux环境中创建静态库和动态库,并且如何使用它们。 **2.1 准备测试代码** 为了方便理解,我们需要准备三个文件:`hello.h`(库头文件)、`hello.c`(库源文件)和`main.c`(主程序)。 - `hello.h`: 定义了库中提供的函数`hello`。 - `hello.c`: 实现了`hello`函数,该函数会在屏幕上输出“Hello XXX!”。 - `main.c`: 测试库文件的主程序,调用`hello`函数。 假设这三个文件的内容如下: **程序1: hello.h** ```c #ifndef HELLO_H #define HELLO_H void hello(const char *name); #endif //HELLO_H ``` **程序2: hello.c** ```c #include "hello.h" void hello(const char *name) { printf("Hello %s!\n", name); } ``` **程序3: main.c** ```c #include "hello.h" int main() { hello("World"); return 0; } ``` **2.2 创建静态库** 1. **编译源文件**: ```bash gcc -c hello.c ``` 生成`hello.o`文件。 2. **创建静态库**: ```bash ar rcs libhello.a hello.o ``` 创建名为`libhello.a`的静态库文件。 3. **使用静态库编译主程序**: ```bash gcc -o main main.c -L. -lhello ``` 使用`-L.`指定静态库所在的目录,并使用`-lhello`链接静态库。 **2.3 创建动态库** 1. **编译并创建动态库**: ```bash gcc -shared -o libhello.so hello.c ``` 创建名为`libhello.so`的动态库文件。 2. **使用动态库编译主程序**: ```bash gcc -o main main.c -L. -lhello ``` 使用同样的命令编译主程序,这次会自动使用动态库。 通过以上步骤,我们可以成功地在Linux环境下创建并使用静态库和动态库。这种方法不仅可以帮助开发者更有效地管理代码,还能够提高程序的性能和可维护性。



剩余15页未读,继续阅读



















- 粉丝: 0
我的内容管理 展开
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助


最新资源
- CADCAM软件在机械制造业中的作用及发展方向.doc
- 世界上主要发达国家或地区电子商务发展情况.doc
- XX供电公司工程项目管理行为规范考评表.doc
- plc在电梯系统中的应用的大学本科方案设计书.doc
- 互联网+的变电检修人数据解决对策.docx
- 全国大学生电子商务竞赛团体赛全流程.doc
- 基于大数据技术的情感分析系统的设计和实现.docx
- 单片机和超声波模式测距系统设计.doc
- 如何在Excel单元格中调整行距.docx
- 新媒体时代高校网络文化建设品牌培育路径研究.docx
- 网络安全期末复习题.doc
- 图形与界面设计illustrator课程教案.doc
- 民用机场建设招投标信息化管理.doc
- 安卓软件工程师IT必须掌握BF-TECH-3.0-C模块.doc
- 装饰工程项目管理的难点与对策15800.doc
- 计算机辅助设计在机械领域的应用分析.docx



评论2