一文教你如何构建自己的函数库
话说ISOC99有自己的一系列标准C函数库,例如我们熟悉的libc.a(包含标准I/O函数、字符串操作函数和整数数学函数)和libm.a(浮点数数学函数),可供我们在使用gcc编译工具编译程序时调用。那么,如果我们在日常学习或项目开发中积累了许多好的函数,希望日后在其他项目中能够复用时,我们又该如何去保存他们呢?今天我就告诉大家怎么办?
1. 看gcc编译器都干了些什么?
所谓,知己知彼,百战不殆。
首先,用一个例子带大家了解一下gcc的编译过程。
//main.c int sum (int *a, int n); int array[2] = {1, 2}; int main() { int val = sum(array, 2); return val; }
//sum.c int sum(int *a, int n) { int i, s = 0; for(i=0; i < n; i++){ s += a[i]; } return s; }
假如一个项目共有以上2个源程序组成。main函数初始化一个整数数组,然后调用一个定义在另一个文件中的sum函数来对数组元素求和。
一般,我们会直接在命令行下键入gcc -Og -o prog main.c sum.c
来直接编译出二进制的可执行的ELF格式的目标文件prog。那在此之间,gcc到底都干了些什么工作呢?
(备注:可以在gcc命令中添加参数-v观察到工作过程。)
看图☞
1.1 cpp预处理
cpp main.c -o main.i
预处理器cpp将源代码main.c翻译成一个ASCII码的中间文件main.i。
1.2 ccl编译
ccl -Og main.i -o main.s
C编译器ccl将中间文件翻译成一个ASCII码的汇编语言文件main.s。
备注:-O参数选择优化级别,由低到高分别为g<1<2<3。一般g和1优化级别用于调试阶段,2和3用于最后交付前的优化阶段。
1.3 as汇编
as main.s -o main.o
汇编器as将汇编文件翻译成一个二进制的可重定位的目标文件main.o。
1.4处理其他源文件
经过相同的步骤,将另一个源文件sum.c转换成sum.o
1.5 ld链接
ld -o prog main.o sum.o
1.6 加载运行
以上步骤都做完之后,最后在命令行(shell)键入./prog
就可以运行啦。shell会调用操作系统中一个叫加载器的函数,它将可执行文件中的代码和数据复制到内存,然后将控制权交给该程序。
2. 创建自己的函数库
假设在某个项目中你自己编写了两个函数addvec() 和mulvec(),感觉很牛逼很好用,希望以后在其他项目里也能用的上。这里有两种方法,一是保存他们的源代码,以后编写程序时插进去;二是将他们加入到一个自己的私有库中,在使用时可在其他文件中直接调用。
前者or后者哪个方便?
如果你选择前者,好的你可以结束阅读课,选择后者,请继续往下看:
2.1 制作目标文件
gcc -c myfuncs.c
将包含你所需要打包的函数的c文件编译成可重定位的目标文件
2.2生成静态库
ar rcs libmyfuncs.a myfuncs.o
利用AR库制作工具,创建我们所需的静态库。
2.3 制作.h头文件
新建一个头文件myfuncs.h,要求其中包含所有myfuncs.a库中函数的原型语句。
3. 使用方法
假设我们在示例程序example.c中需要使用静态库myfuncs.a中的函数。我们该怎么办呢?
3.1 添加头文件;
将头文件myfuncs.h添加到自己的工程目录中,并在example.c文件的顶端添加#include "myfuncs.h"
语句,之后就可以使用库中的函数了。
3.2 编译选项
当你的程序example.c编写完毕后,在编译阶段链接我们的自定义库。
gcc -c example.c gcc -static -o prog example.o -L. -lmyfuncs
第一条语句用来生成目标文件example.o
第二条语句中,-static参数告诉连接器应该构建一个完全链接的可执行目标文件,它可以直接加载到内存并运行,且在加载时无需再做其他链接。-L告诉链接器应该在当前目录下查找库(因为L后面跟的是一个点,而点在linux系统中代表当前目录)。-l后面直接跟你需要链接的库的名字的缩写myfuncs,而不是全称libmyfuncs.a。
注意:链接器还会默认链接C标准函数库libc.a。
获取更多知识,请点击关注:
嵌入式Linux&ARM
CSDN博客
简书博客

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
使用 Jetpack Security 在 Android 上进行数据加密
作者 / Jon Markoff, Staff Developer Advocate, Android Security 您是否尝试过对应用中的数据进行加密?作为开发者,您想要保护数据安全,并确保数据掌握在其合理使用者的手中。但是,大多数 Android 开发者没有专门的安全团队来帮助他们正确地加密应用数据。就算通过网络来搜索如何加密数据,您得到的答案也可能已经过时好几年了,找到的示例也难以保证准确性。 Jetpack Security (JetSec) 加密库为 Files 和 SharedPreferences 对象的加密操作提供了抽象支持。该库使用了安全且运用广泛的 密码学原语 (cryptographic primitives),强化了 AndroidKeyStore 的使用。使用 EncryptedFile 和 EncryptedSharedPreferences 可以让您在本地保护可能包含敏感数据、API 密钥、OAuth 令牌和其他类型机密信息的文件。 从 5.0 开始,Android 会默认 对用户数据分区的内容进行加密,那您为什么还需要加密应用中的数据呢?这是因为在某...
- 下一篇
使用canvas做纯色或渐变色图片优化 img图片拉伸
原文链接:使用canvas做纯色或渐变色图片优化 img图片拉伸 基本思想是对于简单的纯色或者渐变色, 可以使用canvas画出来, 然后导出url, 再在img中缩放拉伸 下面窄的是canvas画的, 理论上只需要画一个像素宽就行了, 下面是img标签渲染的, 拉伸后也不会有模糊, 这种方式可能节省不少流量, 而且加载速度也会快一些, 主要是在一些大型活动中使用, 不过坏处就是必须图像不能太复杂, 不然不太好画 img标签的大小, 最后在外面包一层div, 通过控制外层div的大小来控制img的大小, 而且div可以通过padding实现指定比例的效果 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> <...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- Docker安装Oracle12C,快速搭建Oracle学习环境
- SpringBoot2全家桶,快速入门学习开发网站教程
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- CentOS关闭SELinux安全模块
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- CentOS6,CentOS7官方镜像安装Oracle11G
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Docker使用Oracle官方镜像安装(12C,18C,19C)