1. 共享库概述共享库Shared Library也称为动态链接库Dynamic Link Library是 Linux 系统中一种重要的代码复用机制。与静态库不同共享库在程序运行时才被加载到内存可以被多个程序同时使用从而节省磁盘空间和内存。主要特点运行时加载程序运行时动态加载代码共享多个程序可共享同一份库代码易于更新更新库文件无需重新编译程序节省资源减少磁盘空间和内存占用2. 创建共享库2.1 编写库源代码首先创建两个简单的 C 源文件作为示例hello.c#includestdio.hvoidhello(void){printf(Hello, World!\n);}bye.c#includestdio.hvoidbye(void){printf(Goodbye!\n);}2.2 编译生成位置无关代码PIC共享库需要编译为位置无关代码Position Independent Code, PIC这样库可以在内存的任何位置加载# 编译生成目标文件.o 文件gcc-c-fPIChello.c bye.c-Wall参数说明-c只编译不链接生成目标文件-fPIC生成位置无关代码必须选项-Wall显示所有警告信息执行后会生成hello.o和bye.o两个目标文件。2.3 创建共享库将目标文件链接成共享库# 创建名为 libcommon.so 的共享库gcc-shared-olibcommon.so hello.o bye.o参数说明-shared生成共享库-o libcommon.so指定输出文件名通常以lib开头.so结尾现在你得到了一个名为libcommon.so的共享库文件。3. 使用共享库3.1 编写测试程序创建测试程序test.c#includestdio.h// 声明外部函数voidhello(void);voidbye(void);intmain(){printf(Testing shared library...\n);hello();bye();return0;}3.2 编译链接测试程序编译测试程序并链接共享库# 编译并链接共享库gcc-otesttest.c -L.-lcommon参数说明-L.指定库文件搜索路径.表示当前目录-lcommon链接名为libcommon.so的库去掉lib前缀和.so后缀4. 运行时库路径配置编译成功后运行程序可能会遇到以下错误./test: errorwhileloading shared libraries: libcommon.so: cannotopenshared object file: No suchfileor directory这是因为系统在运行时找不到共享库。Linux 系统通过以下方式查找共享库4.1 方法一复制到系统库目录不推荐将库文件复制到系统标准库目录# 需要 root 权限sudocplibcommon.so /usr/lib/# 或sudocplibcommon.so /lib/缺点污染系统目录可能与其他库冲突。4.2 方法二设置 LD_LIBRARY_PATH 环境变量临时设置仅当前终端有效exportLD_LIBRARY_PATH$LD_LIBRARY_PATH:$(pwd)./test永久设置添加到用户配置文件# 编辑 ~/.bashrc 或 ~/.bash_profileechoexport LD_LIBRARY_PATH$LD_LIBRARY_PATH:/path/to/your/library~/.bashrcsource~/.bashrc4.3 方法三配置 ld.so.conf创建配置文件sudonano/etc/ld.so.conf.d/myapp.conf添加库路径/path/to/your/library更新缓存sudoldconfig5. 调试与验证5.1 查看程序依赖的共享库使用ldd命令查看可执行文件依赖的共享库lddtest输出示例linux-vdso.so.1 (0x00007ffe12345000) libcommon.so /path/to/libcommon.so (0x00007f1234567890) libc.so.6 /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1234567890) /lib64/ld-linux-x86-64.so.2 (0x00007f1234567890)5.2 查看共享库信息使用nm查看库中的符号nm-Dlibcommon.so使用objdump查看库的详细信息objdump-Tlibcommon.so# 查看动态符号表objdump-plibcommon.so# 查看程序头信息5.3 常见错误及解决方法错误 1库版本不匹配./test: /lib/x86_64-linux-gnu/libc.so.6: version GLIBC_2.34 not found解决在较低版本的系统上重新编译库。错误 2库架构不匹配wrong ELF class: ELFCLASS64解决确保库和程序的架构一致32位 vs 64位。错误 3符号未定义undefined symbol: function_name解决检查库是否包含该函数或链接时是否遗漏了必要的库。6. 最佳实践6.1 版本管理为共享库添加版本号# 主版本号.次版本号.修订号gcc-shared-Wl,-soname,libcommon.so.1-olibcommon.so.1.0.0 hello.o bye.oln-slibcommon.so.1.0.0 libcommon.so.1ln-slibcommon.so.1 libcommon.so6.2 编译选项优化# 推荐编译选项gcc-c-fPIC-O2-Wall-Wextra-Werrorhello.c bye.c gcc-shared-Wl,-soname,libcommon.so.1-olibcommon.so.1.0.0 hello.o bye.o