linux下库函数实现

2023-11-03

前言 

C语言是一种结构化程序设计语言,当项目达到一定规模后,采用模块化设计是种必然的选择。所谓模块化设计是指对项目按照“自顶向下”的分析,将项目划分为一个个子系统,每个子系统再划分为多个模块,直到每一模块足够小并且功能单一为止。再按照“自底向上”的方式进行程序设计,将模块用C语言函数来实现,形成逐层调用关系,最终构成整个项目。

模块化设计可以降低程序复杂度,使程序设计、调试和维护等操作简单化。库函数是一种实现模块化的重要手段,在C语言编程中常见的通过包含头文件使用输入输出函数、数学函数等就属于库函数方式。函数库分为静态库和动态库两种,静态库是一系列的目标文件(.o文件)的归档文件(文件名格式为 libname.a),如果在编译某个程序时链接静态库,则链接器将会搜索静态库,从中提取出它所需要的目标文件并直接复制到该程序的可执行二进制文件(ELF格式文件)之中;动态库(文件名格式为 libname.so )在程序编译时并不会被链接到目标代码中,而是在程序运行时才被载入。

静态库的实现

以例子求分数和为例,原例中子函数 multi(m) 和主函数 main() 放在同一源文件中,先将其分成两个不同源文件 multi.c 和test.c。

/*multi.c  这是一个求分数和的函数实现,单独在multi.c文件中,没有其他函数*/

float multi(int m)
{
    int i;
    float s = 0;
    for(i = 1;i <= m;i ++)
    {
        s = s + 1/i;
    }
    
    return s;
}

/*test.c  这是主文件,包含main函数,其中调用multi.c文件中的multi函数*/

#include<stdio.h>
float multi(int m);

void main()
{
    for(int i = 1;i <= 20;i++)
    {
        printf("m=%d,s=%f\n",i,multi(i));
    }
}

可以看到 test. c和 multi.c是调用与被调用关系,下面把 mult.c 编译成静态库。

#gcc -c multi.c

#ar r libmulti.a multi.o

ar: creating libmulti.a

第一行命令用gcc选项表示只编译不链接,因为 multi.c 是单一源文件,所以不需要链接,同时因为文件中没有 main() 函数,链接反而会报错。编译成功后,可以看见在文件夹中生成了 multi.o 文件。

第二行命令是将 mult.o 文件压缩打包到库文件。库文件必须以 lib 开头,以 .a 为扩展名,除开头和扩展名之外的部分,将作为库文件的标识被使用。

ar命令是Linux的一个备份压缩命令,用来做备存文件管理,可以创建、修改备存文件( archive),或从备存文件中抽取成员文件。备存文件以一定的结构打包一个或多个成员文件,且成员文件的内容、模式、时间戳等信息将被保存在备存文件中。

创建成功后,可以看到在文件夹生成了 libmulti.a 文件。至此,由模块文件成功生成了静态库。下面来看,在主文件test.c中怎样使用生成的静态库。首先分析一下 test.c 源文件。在源文件的 main() 函数中使用了 multi 函数,而且在 main() 函数前通过 int multi(intm); 声明了 multi 函数的调用方式。但函数 multi 的函数体定义在 libmulti. a 中,编译时,通过静态方式将 libmulti.a 链接到 test 中,命今如下:

# gcc -o test test.c -L. -l multi

-L. 表示将当前路径加人到库查找路径,这是因为 libmulti.a 目前在当前路径的缘故。可以将静态库文件复制到系统默认的查找路径,这时就可以省略 L. 选项。

-l multi 表示链接 libmulti.a 库文件,请留意文件名的对应。

成功后即可生成 test 可执行程序文件,运行 test 即可看到运行效果。

 

动态库的实现

动态库是函数库的另外一种实现方式。静态库方式下可以看到,在由主文件 test.c 编译生成可执行程序阶段,main() 函数所需的 multi 函数模块一次性从 libmulti.a 中链接到了 test 。此后,生成的 test 可以独立使用,和 libmulti.a 再无关系。因此,静态库方式生成的可执行程序比较大

以动态库方式提供的函数库,只有在使用它的程序执行时才被链接使用,而不将需要的函数模共在编前就链接到可执行文件中,一个动态库以被多个程序同时使用,故可称为共零库,相比静态库,使用动态库会使可执行程序更轻便,函数库升级更容易但部署相对比较困难,因为可执行程序需要和动态库一起才能使用。下面来看动态库方式下函数库的制作及使用过程。

首先将 multi.c 文件制作成动态库:

#gcc-fPIC-shared- c multi.c -o libmulti.so

-fPIC 表示生成和位置无关的代码;-shared指示编译器生成动态库编译成功后,文件夹就会生成 libmulti.so文件,表明生成动态库完成。

下面编译主函数文件,使用生成的动态库:

gcc test.c -L. -l mulIiti -o test

生成 test 后运行./test,即可看到输出结果。

 

参考书

清华大学出版社《嵌入式Linux程序设计》——田卫新

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

linux下库函数实现 的相关文章

  • 小理解

    一 数组指针 数组名本身就是一个指针 指向数组的首地址 如int p 10 表示一个指向10个int元素的数组的一个指针 注意这是声明定长数组时 其数组名指向的数组首地址是常量 而声明数组并使某个指针指向其值指向某个数组的地址 不一定是首地
  • 堆栈详解

    堆区 1 存储的全部是对象 每个对象都包含一个与之对应的class的信息 class的目的是得到操作指令 2 jvm只有一个堆区 heap 被所有线程共享 堆中不存放基本类型和对象引用 只存放对象本身 栈区 1 每个线程包含一个栈区 栈中只
  • 程序设计的基本概念

    程序设计的基本概念 1 程序 2 结构化程序设计 1 程序 由高级语言编写的程序称为 源程序 由C语言编写的程序扩展名为 C 经过 编译 目标程序 后生成文件的扩展名为 obj 经过 链接 可执行程序 后生成文件的扩展名为 exe C语言源

随机推荐

  • System.Net.HttpListenerException (0x80004005): 拒绝访问。

    C 生成的exe突然报错了 原来是被人改了权限配置 我也没改回来 只需要将生成的exe设置成管理员身份运行 往后就不会再报错了
  • 15个免费学习JavaScript的最佳网站

    JavaScript是Web最流行的语言 对于任何Web开发人员来说 JavaScript现在是必须学习的语言 像追踪树这样的创新已经大大提高了JavaScript的性能 并且它在所有开发人员中越来越受欢迎 如果您想要事业得到进一步的发展
  • Python 基础——range() 与 np.arange()

    range 返回的是range object 而np arange 返回的是numpy ndarray type np arange 10 np ndarray 两者都是均匀地 evenly 等分区间 range尽可用于迭代 而np ara
  • Images之Dockerfile中的命令2

    COPY COPY has two forms COPY chown
  • cocos2dx中毒冰冻shader

    中毒效果 ifdef GL ES precision mediump float endif uniform sampler2D u texture varying vec2 v texCoord varying vec4 v fragme
  • 《深入理解Java函数式编程》系列文章

    Introduction 本系列文将帮助你理解Java函数式编程的用法 原理 本文受启发于JavaOne 2016关于Lambda表达式的相关主题演讲Lambdas and Functional Programming和Refactorin
  • 在Python环境下使用pgmpy构建动态贝叶斯网络并进行参数学习(附详细代码)

    首先列举当前主要构建贝叶斯网络的一些工具 1 软件 Netica SMILE 2 MATLAB包 BNT 3 Python包 pgmpy libpgm pomegranate 4 R包 dbnlearn 如果是单纯的进行贝叶斯网络的学习与推
  • html弹窗代码只弹窗一次,信息弹窗提示一天只弹出一次js代码

    信息弹窗提示一天只弹出一次js代码 通过jquery cookie js实现功能 避免重复弹出 弹窗提示 margin 0 padding 0 alert windows display none position absolute z i
  • 计算机网络第八版详细思维导图复习(可复制修改)

    按照我们学校的教学课本 计算机网络第八版 谢希仁 计算机网络自顶向下第七版 老师习题讲解课件 B站 计算机网络微课堂 有字幕无背景音乐版 王道计算机考研 计算机网络 湖科大深入浅出计算机网络 示范教学包等途径整合而成 有个人总结和自己的思考
  • 使用SVG+React实现飞行仪表仿真

    SVG React实现 演示地址 https liujialun github io i
  • 深入理解Mysql底层数据结构

    一 索引的本质 索引是帮助MySQL高效获取数据的排好序的数据结构 二 索引的数据结构 二叉树 红黑树 Hash表 BTree B Tree mysql的索引采用的是B 树的结构 mysql为什么不用二叉树 因为对于单边增长的数据列 二叉树
  • SSE2介绍及其简单用法举例

    SSE2 全名为Streaming SIMD Extensions 2 是一种IA 32架构的SIMD指令集 SSE2是在2001年随着Intel发表第一代Pentium 4处理器也一并推出的指令集 它延伸较早的SSE指令集 而且可以完全取
  • 腾讯开启薪酬改革,晋升不调薪,需要结合业绩评估

    六月的第一天有媒体爆出 腾讯全员收到邮件 公司开启新一轮的薪酬改革 邮件中的重点内容是 公司认可晋升代表能力提升以及更高的职责要求 同时也要求将能力转化为业绩贡献 所以年度薪资回顾时会结合业绩贡献 能力提升 薪酬竞争力等因素综合评估 腾讯公
  • stable diffusion--二次元福利

    继上次用stable diffusion生成谪仙男子外貌翻车后 痛定思痛 发现用stable diffusion webui这个神器 效果出乎意料的好 01 安装教程 1 pytorch安装 具体安装可查看我之前的图文libtorch导入模
  • Object.defineProperty()方法的使用

    在我们学习到Vue响应式原理的时候 必然要了解到JS里Object defineProperty 方法 底层就是用这个方法来实现的 可以实现对象的简单代理 Object defineProperty 方法会直接在一个对象上定义一个新属性 或
  • SQL中如何使用EXISTS替代IN

    我们在程序中一般在做SQL优化的时候讲究使用EXISTS带替代IN的做法 理由是EXISTS执行效率要比IN高 之前我一直挺懵懂的一件事情是如何使用EXISTS来替换IN呢 二者表示的意义又是什么呢 今天就我个人理解记录一下 IN表示范围
  • STM32学习心得二十五:光敏传感器原理及实验

    记录一下 方便以后翻阅 主要内容 1 光敏传感器概述 2 相关实验代码解读 实验功能 通过ADC3 CH6来检测光敏二极管一端的电压变化来达到检测光强的目的 可通过检测环境光 调节LCD的背光大小 官方资料 STM32中文参考手册V10 第
  • 什么是XSS(跨站)攻击

    XSS 跨站 攻击的概念 XSS又叫CSS Cross Site Script 跨站脚本攻击 它指的是恶意攻击者往Web页面里插入恶意html代码 当用户浏览该页之时 嵌入其中Web里面的html代码会被执行 从而达到恶意用户的特殊目的 X
  • L2-030 冰岛人

    2018年世界杯 冰岛队因1 1平了强大的阿根廷队而一战成名 好事者发现冰岛人的名字后面似乎都有个 松 son 于是有网友科普如下 冰岛人沿用的是维京人古老的父系姓制 孩子的姓等于父亲的名加后缀 如果是儿子就加 sson 女儿则加 sdot
  • linux下库函数实现

    前言 C语言是一种结构化程序设计语言 当项目达到一定规模后 采用模块化设计是种必然的选择 所谓模块化设计是指对项目按照 自顶向下 的分析 将项目划分为一个个子系统 每个子系统再划分为多个模块 直到每一模块足够小并且功能单一为止 再按照 自底