博客
关于我
Linux静态库和共享库【转】
阅读量:789 次
发布时间:2023-02-05

本文共 2661 字,大约阅读时间需要 8 分钟。

静态库与共享库的比较及使用方法

静态库和共享库是程序开发中常用的二进制库文件形式,两者在功能和使用场景上有显著差异。本文将从静态库的特点、编写方法、使用方法以及共享库的运行机制等方面进行详细介绍。

1. 静态库的特点

静态库(Static Library)是一种在编译时与程序链接的库文件,其主要特点是:

  • 包含函数代码的声明和实现
  • 所有代码都会嵌入到宿主程序中
  • 只在编译阶段使用,不影响程序的执行

例如,在 Windows 环境中常见的静态库文件为 .lib 格式,程序在编译时会将这些库文件链接到最终可执行文件中。

2. 静态库的编写

编写静态库的过程通常包括以下几个步骤:

  • 编写源代码:创建包含函数实现的代码文件。
  • 使用 AR 工具生成静态库:通过工具将多个 .obj 文件打包成一个 .a.lib 文件。
  • 以下是一个简单的示例:

    // addvec.cvoid addvec(int* x, int* y, int* z, int n) {    int i = 0;    for (; i < n; ++i) {        z[i] = x[i] + y[i];    }}

    3. 静态库的使用

    使用静态库时,通常需要在编译命令中添加 -l 标志来链接库文件。例如,以下是一个使用静态库的示例:

    // test2.c#include 
    #include
    int x[2] = {1, 2};int y[2] = {3, 4};int z[2] = {0};int main() { addvec(x, y, z, 2); printf("z = [%d %d]\n", z[0], z[1]); return 0;}

    4. 共享库的特点

    共享库(Shared Library)与静态库的主要区别在于:

    • 包含函数代码的声明和实现
    • 只在程序运行时使用,由动态链接器加载
    • 可以根据需要动态加载或卸载

    共享库根据加载时机可以分为两种类型:

  • 自身加载型共享库:在程序加载时由动态链接器自动加载。
  • 运行时加载型共享库:无需编译时链接,可在程序运行时动态加载。
  • 5. 自身加载型共享库的使用

    使用自身加载型共享库时,编译工具会生成特定的代码。以下是一个示例:

    // main.c#include 
    #include
    int x[2] = {1, 2};int y[2] = {3, 4};int z[2] = {0};int main() { void (*addvec)(int*, int*, int*, int); void* handle; handle = dlopen("./libvector.so", RTLD_LAZY); if (!handle) { printf("无法打开共享库\n"); return 1; } addvec = dlsym(handle, "addvec"); if (addvec == NULL) { printf("无法加载addvec函数\n"); return 1; } addvec(x, y, z, 2); printf("z = [%d %d]\n", z[0], z[1]); if (dlclose(handle) < 0) { printf("无法卸载共享库\n"); return 1; } return 0;}

    6. 运行时加载型共享库的使用

    运行时加载型共享库的使用通常涉及动态链接库(DLL)的加载和卸载。Linux 系统提供了以下 API 来实现这一功能:

    • dlopen:打开共享库文件并返回句柄。
    • dlsym:根据句柄获取符号的地址。
    • dlclose:卸载共享库。
    • dlerror:获取错误信息。

    7. 运行时加载型共享库的示例

    以下是一个使用 dlopendlsym 的示例:

    #include 
    #include
    #include
    int x[2] = {1, 2};int y[2] = {3, 4};int z[2] = {0};int main() { void* handle; void (*addvec)(int*, int*, int*, int); char* error; handle = dlopen("./libvector.so", RTLD_LAZY); if (!handle) { printf("无法打开共享库: %s\n", dlerror()); return 1; } addvec = dlsym(handle, "addvec"); if ((error = dlerror()) != NULL) { printf("无法加载addvec函数: %s\n", error); return 1; } addvec(x, y, z, 2); printf("z = [%d %d]\n", z[0], z[1]); if (dlclose(handle) < 0) { printf("无法卸载共享库: %s\n", dlerror()); return 1; } return 0;}

    8. 共享库的加载方式

    在使用共享库时,通常会通过编译器标志 -shared 生成共享库文件。例如,以下是一个生成共享库的命令:

    gcc -fPIC -o libvector.so -shared vector.o

    通过上述方法,可以轻松实现程序的动态加载和卸载,提升程序的可扩展性和灵活性。

    9. 总结

    静态库和共享库是软件开发中常用的工具,两者在功能和使用场景上各有优势。静态库适合在编译时完成所有准备,而共享库则更适合在程序运行时动态加载以提高灵活性。选择哪种方式取决于具体的开发需求和项目复杂度。

    转载地址:http://mrkfk.baihongyu.com/

    你可能感兴趣的文章
    Linux语言配置
    查看>>
    Linux课题实践四——ELF文件格式分析
    查看>>
    Linux调优工具tuned
    查看>>
    Linux调度器 - 进程优先级
    查看>>
    Linux负载CPU、内存、磁盘IO、网络IO状态分析详解
    查看>>
    Linux账号安全——用户登陆权限
    查看>>
    Linux资产管理与服务器运行状态监控脚本
    查看>>
    Linux超级强大的十六进制dump工具:XXD命令,我教你应该如何使用!
    查看>>
    Linux路径格式与Window路径格式的转换(附Python代码)
    查看>>
    linux踢掉线上用户
    查看>>
    Linux踢掉远程登录用户
    查看>>
    Linux软RAID(MDAMD)使用实战
    查看>>
    Linux软件包源码编译安装实战
    查看>>
    linux软件包的一般安装方法
    查看>>
    Linux软件包管理与Vim编辑器指南
    查看>>
    linux软件包:RPM包、源码包、yum在线
    查看>>
    linux软件安装与卸载
    查看>>
    Linux软硬链接详解
    查看>>
    Linux输入错误字符 删除显示^H和快速删除命令
    查看>>
    Linux运维之道之网络基础学习1.3
    查看>>