目录

LInux中函数库的类型

一、用gcc生成.a静态库

1.编辑生成例子程序 hello.h 、hello.c和main.c

2.将hello.c编译成.o文件

3.由.o文件创建静态库

4.在程序中使用静态库

二、用gcc创建动态库文件

1.由.o文件创建动态库

2.在程序中使用动态库

3.当静态库与动态库同名时,gcc命令会使用哪个库

三、实操1

1.构建新文件夹,编写程序

2.静态库.a文件的生成与使用

3.共享库.so文件的生成与使用

四、实操2

1.c程序的编写

2.用gcc分别把三个.c文件分别编译成3个.o目标文件

3.将目标文件生成静态.a文件 并与main函数连接

4.观测静态库文件大小

5.将目标文件生成动态库.so文件并与main函数连接

6.观测动态库文件大小 并与静态库文件大小进行比较

五、总结

六、参考资料


LInux中函数库的类型

函数库分为静态库和动态库。

静态库:

在程序编译时会被连接到目标代码中,程序运行是则不需要静态库的存在。

动态库:

在程序编译时不会被连接到目标代码中,而是程序运行时载入的。

两者区别:前者是编译连接的,后者是程序运行载入的。

一、用gcc生成.a静态库

1.编辑生成例子程序 hello.h 、hello.c和main.c

先创建一个目录,保存本次练习的文件

输入指令 mkdir test1(创建目录)

cd test1(选中该目录路径)

然后用vim、nano或者gedit等文本编辑器生成所需要的三个文件。我用的是vim。

hello.c是函数库的源程序,其中包含了公用函数hello,该函数将在屏幕上输出“Hello XXX!”。hello.h为该函数库的头文件。main.c为测试库文件的主程序,在主程序中调用了公用函数hello。

三个程序如下:

hello.h

#ifndef HELLO_H
#define HELLO_H
void hello(const char*name);
#endif//HELLO_H

hello.c

#include<stdio.h>
void hello(const char*name)
{printf("Hello %s!\n",name);
}

main.c

#include"hello.h"
int main()
{hello("everyone");return 0;
}

2.将hello.c编译成.o文件

输入命令 gcc -c hello.c

我们可以运行ls命令看看是否生成了hello.o文件

如图所示,则成功生成了hello.o文件

3.由.o文件创建静态库

静态库的文件名的命名规范是以lib为前缀,紧接着跟静态库名,扩展名为.a。例如:我们将创建的静态库名为myhello,则静态库文件名就是libmyhello.a。(在创建和使用静态库时,需要注意这点       点)

输入命令 ar -crv libmyhello.a hello.o 生成静态库

同样的可以用ls命令查看是否成功生成静态库

如图,已经有了libmyhello.a,则生成静态库成功

4.在程序中使用静态库

要是用静态库中内部的函数,只需要在使用到这些公用函数的源程序包含这些公用函数的原型声明,然后再用gcc命令生成目标文件时指明静态库名,gcc将会从静态库中将公用函数连接到目标文件中。注意,gcc会在静态库名前加上前缀lib,然后追加.a得到的静态库文件名来查找静态库文件。以下介绍了三种方法:

第一种:

输入命令 gcc -o hello main.c -L. -lmyhello

自定义的库时,main.c还可放在-L. 和 -lmyhello 之间,但是不能放在它俩之后,否则会同时myhello没定义,但是是系统的库时,如g++ -o main (-L/usr/lib) -lpthread main.cpp就不出错。

方法二:

输入命令 gcc main.c libmyhello.a -o hello

方法三:

先输入命令 gcc -c main.c 生成main.o文件

再输入命令 gcc -o hello main.o libmyhello.a 生成可执行文件

再输入命令 ./hello 运行

二、用gcc创建动态库文件

1.由.o文件创建动态库

动态库文件名命名规范和静态库文件名命名规范类似,也是在动态库名增加前缀lib,但其文件扩展名为.so。例如:我们将创建的动态库名为myhello,则动态库文件名就是libmyhello.so。

输入命令 gcc -shared -fPIC -o libmyhello.so hello.o 创建动态库

也可通过ls命令查看动态库是否创建成功

2.在程序中使用动态库

在程序中使用动态库和使用静态库完全一样,也是在使用到这些公用函数的源程序中包含这些公用函数的原型声明,然后再用gcc命令生成目标文件时指明动态库名进行编译。我们先运行gcc命令生成目标文件,在运行它看看结果。

输入命令 gcc -o hello main.c -L. -lmyhello(或 gcc main.c libmyhello.so -o hello 不会出错(没有libmyhello的话,会出错),但是接下来 ./hello 会提示出错,因为虽然连接时用的是当前目录的动态库,但是运行时,是到 /usr/lib 中找库文件的,将文件 libmyhello.so 复制到目录 /usr/lib 中就OK了(即输出命令 sudo cp libmyhello.so /usr/lib ),然后再运行 ./hello 就没问题了)

如上图,成功了。这也进一步说明了动态库在程序运行时是必要的。

3.当静态库与动态库同名时,gcc命令会使用哪个库

先删除除.c 和 .h 外所有的文件,恢复成我们刚刚编程完举例程序状态

输入命令 sudo rm -f hello hello.o /usr/lib/libmyhello.so

ls

再来创建静态库文件libmyhello.a和动态库libmyhello.so

输入命令 gcc -c hello.c

ar -crv libmyhello.a hello.o

gcc -shared -fPIC -o libmyhello.so hello.o

ls

运行gcc命令来使用函数库 myhello 生成目标文件 hello,并运行程序 hello

输入命令 gcc -o hello main.c -L. lmyhello

./hello

如图红框所标识的地方,发现在执行可执行文件时,会报一个错误,可见当静态库和动态库同时存在的时候,程序会优先使用动态库。(按照上面一样的操作将文件路径复制到 /usr/lib 下即可解决报错问题)

三、实操1

1.构建新文件夹,编写程序

mkdir test2

cd test2

A1.c

#include<stdio.h>
void print1(int arg);
{printf("A1 print arg:%d\n",arg);
}

A2.c

#include<stdio.h>
void print2(char *arg)
{printf("A2 printf arg:%s\n",arg);
}

A.h

#ifndef A_H
#define A_H
void print1(int);
void print2(char *);
#endif

test.c

#include<stdlib.h>
#include"A.h"
int main()
{print1(1);print2("test");exit(0);
}

2.静态库.a文件的生成与使用

gcc -c A1.c A2.c

ar crv libafile.a A1.o A2.o

gcc -o test test.c libafile.a

./test

3.共享库.so文件的生成与使用

gcc -c -fpic A1.c A2.c

gcc -shared *.o -o libafile.so

gcc -o test test.c libafile.so

./test

此处会报错,问题在于路径,只需要通过以下命令将其放在 /usr/lib 目录下即可

sudo cp libafile.so /usr/lib

./test

四、实操2

1.c程序的编写

mkdir test3

cd test3

lcx.c

float x2x(int a,int b)
{float ans;ans=a+b;return ans;
}

lcy.c

float x2y(int a,int b)
{float ans;ans=a-b;return ans;
}

lc.h

#ifndef LC_H
#define LC_H
float x2x(int a,int b);
float x2y(int a,int b);
#endif

main.c

#include<stdio.h>
#include"lc.h"
int main()
{int a,b;a=8;b=5;float ans1;float ans2;ans1=x2x(a,b);ans2=x2y(a,b);printf("%f\n",ans1);printf("%f\n",ans2);return 0;
}

2.用gcc分别把三个.c文件分别编译成3个.o目标文件

gcc -c lcx.c lcy.c main.c

ls

3.将目标文件生成静态.a文件 并与main函数连接

ar crv libic.a lcx.o lcy.o

ls

gcc -o main main.o libic.a

4.观测静态库文件大小

在linux下可使用 “ls -l” 或者 “ls -al” 或者 “ll” 命令查看文件及目录详情

5.将目标文件生成动态库.so文件并与main函数连接

gcc -shared -fPIC -o libic.so lcx.o lcy.o

ls

gcc -o main main.o libic.so

6.观测动态库文件大小 并与静态库文件大小进行比较

将二者进行对比,发现静态库较动态库而言,占用空间更少。

五、总结

通过上述几个程序基于Ubuntu中gcc生成静态库和动态库的练习,让我进一步明白了静态库与动态库之间的差别。同时也培养了处理问题的耐心,在不断的网上查阅资料后能处理所遇到的各种问题。也让我看到了这和代码编辑器完全不同,虽然这种方式更复杂,但却能让我对代码的编译过程有更清晰更深刻的理解与认识。

六、参考资料

浏览https://mooc1.chaoxing.com/ueditorupload/read?objectId=dc36405faf8e7dc66d657fcc6b780cd7&fileOriName=%25E7%2594%25A8gcc%25E7%2594%259F%25E6%2588%2590%25E9%259D%2599%25E6%2580%2581%25E5%25BA%2593%25E5%2592%258C%25E5%258A%25A8%25E6%2580%2581%25E5%25BA%2593.pdf浏览https://mooc1.chaoxing.com/ueditorupload/read?objectId=07cf0524899ab88f4d59af8e05a94d8a&fileOriName=%25E9%259D%2599%25E6%2580%2581%25E5%25BA%2593.a%25E4%25B8%258E.so%25E5%25BA%2593%25E6%2596%2587%25E4%25BB%25B6%25E7%259A%2584%25E7%2594%259F%25E6%2588%2590%25E4%25B8%258E%25E4%25BD%25BF%25E7%2594%25A8.pdf

Ubuntu下gcc的静态库与动态库的生成与使用相关推荐

  1. Ubuntu下GCC引用mysql头文件和库文件

    1.安装mysql-server: sudo apt-get install mysql-server-5.1 2.gcc连接mysql的库安装: sudo apt-get install libmy ...

  2. linux 中如何将文件粘贴到usr下的lib内,学会在Linux下GCC生成和使用静态库和动态库...

    一.基本概念1.1什么是库 在windows平台和linux平台下都大量存在着库. 本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行. 由于windows和linux的平台不同(主 ...

  3. Linux下Gcc生成和使用静态库和动态库详解

    参考文章:http://blog.chinaunix.net/uid-23592843-id-223539.html 一.基本概念 1.1什么是库 在windows平台和linux平台下都大量存在着库 ...

  4. Linux下GCC生成和使用静态库和动态库详解(二)

    2.1准备好测试代码hello.h.hello.c和main.c: hello.h(见程序1)为该函数库的头文件. hello.c(见程序2)是函数库的源程序,其中包含公用函数hello,该函数将在屏 ...

  5. 在Linux下如何使用GCC编译程序、简单生成静态库及动态库。

    在Linux下如何使用GCC编译程序.简单生成 静态库及动态库.   本文适用于Linux下开发初学者.本文初步讲解在Linux下如何使用GCC编译程序.简单生成静态库及动态库. 一.关于安装.一般系 ...

  6. Linux下Gcc生成和使用静态库和动态库详解(转)

    一.基本概念 1.1什么是库 在windows平台和linux平台下都大量存在着库. 本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行. 由于windows和linux的平台不同( ...

  7. Linux下用gcc生成静态库和动态库及练习使用OpenCV

    我们通常把一些公用函数制作成函数库,供其它程序使用.函数库分为 静态库和动态库两种.静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库.动态库在程序编译时并不会被连接到目标代码中,而 ...

  8. gcc生成静态库和动态库,以及OpenCV3.4.11的安装和实例

    文章目录 一.用gcc生成静态库和动态库 (1).hello使用库实例 1.创建目录并编写hello代码 2.gcc编译得到.o文件 3.静态库的使用 4.动态库的使用 5.静态库与动态库的对比 (2 ...

  9. GCC生成静态库和动态库

    目录 1)阅读.理解和学习材料"用gcc生成静态库和动态库.pdf"和"静态库.a与.so库文件的生成与使用.pdf",请在Linux系统(Ubuntu)下如实 ...

最新文章

  1. IANA定义的常见服务的端口号列表
  2. 【数据结构】二叉树的应用。
  3. 【转】如何编译一个内核 - Ubuntu方式
  4. Python使用scipy包将稀疏矩阵保存为Mtx格式和npz格式文件实战
  5. LeedCode: 计算器专场
  6. C语言 sizeof 和 strlen 函数区别 - C语言零基础入门教程
  7. 301重定向IIS设置,及伪静态后 301重定向出错案例分享
  8. shell获取命令结果返回行数(行个数)
  9. 金山云上市首日暴涨 40%,雷军:「All in」才有机会胜出
  10. 4周第4次课 压缩打包介绍 gzip bzip2 xz压缩工具
  11. DXUT扩展之摄像机
  12. 构建自己的PHP框架(邮件发送)
  13. 使用Cmder替换cmd,让你的开发飞起来
  14. 自考计算机毕业论文范文,计算机信息论文范文 计算机信息类有关自考毕业论文范文5000字...
  15. 图像超分辨率论文笔记
  16. Go开发 之 容器(数组Array、切片slice、映射map、列表list)
  17. zipfile的压缩和解压缩
  18. excel数字排序1后面是2而不是10
  19. CPLD/FPGA 内部结构与原理
  20. SQL Server2012在程序开发中实用的一些新特性

热门文章

  1. 记录达梦一次IO问题的分析
  2. python网络课程答案_Python语言应用知到网课答案
  3. 非平稳信号的频谱分析方法---(短时傅立叶变换)
  4. 网站推荐:archimy.com 在线函数图象绘制
  5. assertThat断言测试方法
  6. 浏览器创建render 树_如何为浏览器创建出色的游戏
  7. windows系统锁定计算机组合键,WIN键间断性触发在锁定状态!!
  8. python 爬虫 关于requests的基础知识及常用的一些User-Agent
  9. npm 版本更新指令
  10. 【IDEA用法】IDEA新建文件自动加入SVN,删除文件自动从SVN中删除