**Linux 知识补充 -- 动态链接库的编译与使用** 1652270 **冯舜** Linux 下的动态链接库 ============================ 准确来说, 动态链接库 (Dynamic-linked Library) 是 Microsoft Windows 下对于共享函数库的实现方式. Linux 下的 "动态链接库" 是 "共享库 (Shared Library)", 通常取 `.so` 扩展名. 共享库是独立于引用它的可执行文件而存在的函数库文件, 它被用作动态链接和运行时载入, 为可执行文件提供库函数. 与静态库不同, 共享库不会在链接时被合入可执行文件中, 而只是在可执行文件的动态符号表中登记名字, 并独立存在于系统的库目录中, 以便需要时被调用. 多个可执行文件可共用一个共享库, 而非各自以内置静态库的方式实现要调用的函数, 这显然有利于空间重用, 节省磁盘空间. C/C++ 共享库在编译时需要指定选项 `-fPIC` (Position Independent Code, 使代码可随处被调用), 链接时需要指定选项 `-shared -Wl,-soname,(共享库文件名)`. 这样便能生成出可动态调用的共享库. 而需要与共享库动态链接的可执行文件在链接时要指定选项 `-L(共享库目录) -l(共享库名)`. 动态链接库在各操作系统中被广泛使用. 如作业用到的虚拟机 CentOS 系统中, 大多数程序的底层 C 库调用都是指向动态链接库 `libc.so` 而非内部实现. 如最简单的含 `printf("Hello world!");` 的 C 代码, 用 `gcc` 默认编译后运行, 其 `printf` 函数引用的是 `libc` 共享库中的函数. 动态链接库测试样例 ============================ ## 建立子目录 如//mkdir3//, 建立了子目录. !![mkdir3,建立子目录] ## 子目录 01 下建立动态链接库 如//somakefile//, 在子目录 `01` 下建立 `test1.c` `test2.c` `makefile`. !![somakefile,建立源文件和 `Makefile`] 运行 `make`, 构建过程正常完成. 用 `LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.` 添加当前目录到动态库搜索路径后, 在同一行内运行 `./test2`, 发现正常运行. 但去掉 `LD_LIBRARY_PATH` 的定义便会出 "加载共享库失败" 的错误. 运行 `make clean`, 清理过程正常完成. 整个构建、运行、清理过程如//somakerun//. !![somakerun,构建、运行、清理过程] ## 子目录 02 下建立动态链接库 如//cppsomakefile//, 在子目录 `02` 下建立 `test1.cpp` `test2.cpp` `makefile`. !![cppsomakefile,建立源文件和 `Makefile`] 运行 `make`, 构建过程正常完成. 用 `LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.` 添加当前目录到动态库搜索路径后, 在同一行内运行 `./test2`, 发现正常运行. 但去掉 `LD_LIBRARY_PATH` 的定义便会出 "加载共享库失败" 的错误. 运行 `make clean`, 清理过程正常完成. 整个构建、运行、清理过程如//cppsomakerun//. !![cppsomakerun,构建、运行、清理过程] ## 上层目录 Makefile "Linux 知识补充 -- Makefile 文件的作用及编写方法" 中撰写的上层目录 `Makefile` 可直接拿来用. !![copymakefile,复制上层目录 Makefile 过来] !![sorootmakefile,上层目录 Makefile 的内容] 构建、运行、清理过程如//sorootmakerunclean//. !![sorootmakerunclean,上层目录里构建、运行、清理]