C语言静态库与动态库

库 是一种代码的二进制的封装形式,将.o文件打包封装就成了库。库可以在任何地方使用,但用户却不能看见他的具体实现。库有利于代码模块化,只要接口设计得合理,改变库的内部实现,不会影响到用户级别的代码使用。

动态库

1.封装动态库
假设有源代码sum.c, sub.c

gcc sum.c -c -o sum.o
gcc sub.c -c -o sub.o
//封装成库
gcc -shared -fPIC -o libmymath.so sum.o sub.o
/*
-shared 表示要编译一个共享库
-fPIC 表示要生成与位置无关的代码
-o 要创建的库的名称,一般约定库的名称格式如下:
        lib库名.so
*/

2.动态库的编译
只需把.h与.so文件提供给用户使用即可
用户编译形式如下:

gcc main.c  -I 头文件路径 -L 库文件路径 -l库名
ex:
    gcc test.c -I ../mymath/ -L ../mymath/ -lmymath
//路径可以是相对路径也可以是绝对路径

3.依赖动态库的程序执行
用户执行时需要指明库所在的路径,通常通过添加环境变量的方式实现
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:库文件路径
查看库环境变量
echo $LD_LIBRARY_PATH

使用命令lld可查看

静态库

1.封装静态库
假设有源代码sum.c, sub.c

gcc sum.c -c -o sum.o
gcc sub.c -c -o sub.o
//静态库的后缀名是.a
ar -rc libmymath.a  sum.o sub.o
//-rc 中的r 表示插入目标文件到静态库中,c表示创建指定的静态库

2.静态库编译

gcc main.c  -I 头文件路径 -L 库文件路径 -l库名
ex:
    gcc test.c -I ../mymath/ -L ../mymath/ -lmymath
//如果该路径下有动态库,则会优先使用动态库

//如果要静态链接自己或第三方的库,但又要动态链接系统的库,那么编译方式如下
gcc xxx.c -I 头文件路径 静态库的完整的名称
ex:
    gcc xxx.c -I ../mymath/ ../mymath/libmymath.a

//全部使用静态库,在编译时加 -static
gcc main.c  -I 头文件路径 -L 库文件路径 -l库名 -static

动态库与静态库的主要区别

静态库和动态库都是二进制文件(目标文件)的封装

对于动态库,编译程序时,并没有把动态库的内容复制到可执行文件中去,仅仅是做了一个标记,表示可执行文件需要用到某个动态库,当执行程序时,首先需要去LD_LIBRARY_PATH指定的路径下(或库的标准路径,如/lib,如/usr/lib等)查找需要的动态库,才能正常运行。

对于静态库,编译程序时,会把静态库中的内容复制到可执行文件中去,运行程序时,就不再需要那个静态库了。

我们使用得最多的是动态库,理由:
1、程序运行时,动态库在内存中只需要一份,而静态库,则可能会有多份拷贝,造成所谓的代码
冗余。
2、当库更新升级时,对于动态库来说只要接口不变,则不需要重新编译用户程序,如果是静态库,则库改变了,所有使用该库的程序都必须重新编译。

C&C++混合编程中库的处理

c++兼容c,能够直接使用这些功能,用c开发的功能如果打包成库了(经c编译器编译成目标文件),目标文件中的函数名就已经确定下来。而c++编译器会对函数名进行处理,会由于函数名字不匹配而导致调用c库中的函数失败

解决办法:
C++提供了一个关键字: extern “C”, 称为链接指示,通常写在头文件中。但c编译器并不认识这个关键字。因此用法如下:

#ifdef __cplusplus
extern "C"
{
#endif

    int sum(int a, int b); // C函数声明
    int sub(int a, int b); // 可包含多个函数声明

#ifdef __cplusplus
}
#endif

负责任的程序员,理应在c语言编写的库中加入该关键字

Original: https://www.cnblogs.com/left23333/p/16350034.html
Author: Left23333
Title: C语言静态库与动态库

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/582418/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Java常见知识点总结

    1 重载 && 重写 重载: 发生在同一个类中, 方法名必须相同,参数类型不同、个数不同、顺序不同,方法返回值和访问修饰符可以不同,发生在编译时。 重写: 发生在父…

    Linux 2023年6月7日
    0101
  • Tensorflow

    1.什么是Tensorflow? Tensor(张量)意味着 N 维数组,Flow(流)意味着基于数据流图的计算,TensorFlow即为张量从图的一端流动到另一端。 它支持CNN…

    Linux 2023年6月6日
    095
  • 【演讲】2020年马云谈疫情过后的新风口

    2020年马云谈疫情过后的新风口 【关键词】:疫情、新风口、数字化趋势、传统行业转型、教育 一、演讲背景 背景 2020线上智博会,马云8分钟演讲30次提到数字化 原视频 2020…

    Linux 2023年6月13日
    0114
  • 基于spring security创建基本项目框架

    SpringBoot建项目步骤 建表 新建项目 (package name可以自定义,整个项目只能在该包下) 选择可能有到的依赖 (别忘了勾选SQL中的Mybatis Framew…

    Linux 2023年6月7日
    091
  • PHP str_repeat()

    str_repeat str_repeat() 函数把字符串重复指定的次数。 示例: function strRepeat() { echo str_repeat("*&…

    Linux 2023年6月7日
    0185
  • 4.7 Linux压缩文件或目录中文件为.bz2格式(bzip2命令)

    bzip2 命令同 gzip 命令类似,只能对文件进行压缩(或解压缩),对于目录只能压缩(或解压缩)该目录及子目录下的所有文件。当执行压缩任务完成后,会生成一个以”.b…

    Linux 2023年6月7日
    0118
  • nginx配置文件讲解及示例(可复制)

    【示例一】 运行用户 user www-data; 启动进程,通常设置成和cpu的数量相等 worker_processes 1; 全局错误日志及PID文件 error_log /…

    Linux 2023年6月6日
    085
  • 最新超详细VMware下CentOS系统安装

    一、了解CentOS系统 CentOS是免费的、开源的、可以重新分发的开源操作系统,CentOS(Community Enterprise Operating System,中文意…

    Linux 2023年5月27日
    098
  • RPA 抖音机器人汇总

    bash;gutter:true; 一、RPA 抖音小店催好评机器人 RPA机器人详情: 1、配置好抖音小店订单号与催好评话术 2、启动抖音小店催好评机器人 3、机器人打开飞鸽客服…

    Linux 2023年6月7日
    093
  • js学习笔记——条件 循环

    今天发现之前学的爱前端的课中JS部分函数等不全,果断换了一个课——渡一的《Web前端开发JavaScript高薪课堂》接着学习,不过废话有点多 语法:1、单if,条件成立,执行语句…

    Linux 2023年6月13日
    075
  • 我懂得了什么

    站在24岁的这个档口,没有学业又没有工作的时刻,前不着村后不着店。我觉得应该要写一些总结,虽然年仅24的我相比老人家总结不出更深刻的道理,但是现在是互联网的时代,获取知识的途径已经…

    Linux 2023年6月6日
    0105
  • ASP.NET Core 3.0 : 二十五. TagHelper

    什么是TagHelper?这是ASP.NET Core 中新出现的一个名词,它的作用是使服务器端代码可以在Razor 文件中参与创建和呈现HTML 元素。(ASP.NET Core…

    Linux 2023年6月7日
    0102
  • SSH免密登录的配置

    ssh登录 登录ssh一般情况有两种方法 密码登录 秘钥登录(免密) 大部分情况我们选择都是输入密码登录,平常使用暂时没有遇到什么问题。最近我编写了一些使用scp来传输文件的脚本,…

    Linux 2023年6月6日
    055
  • Java50个关键字之static

    关键字static主要有两种作用:第一,为某特定数据类型或对象分配单一的存储空间,而与创建对象的个数无关。第二,希望某个方法或属性与类而不是对象关联在一起,也就是说,在不创建对象的…

    Linux 2023年6月7日
    0103
  • 内网渗透测试:利用DCOM进行横向渗透——利用ExecuteShellCommand在做远程命令执行

    COM COM即组件对象模型(Component Object Model,COM) ,是基于 Windows 平台的一套组件对象接口标准,由一组构造规范和组件对象库组成。COM是…

    Linux 2023年5月28日
    090
  • Unicode、UTF-8、UTF-16 终于懂了

    计算机起源于美国,上个世纪,他们对英语字符与二进制位之间的关系做了统一规定,并制定了一套字符编码规则,这套编码规则被称为ASCII编码 ASCII 编码一共定义了128个字符的编码…

    Linux 2023年6月13日
    0108
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球