嵌入式02.1:用gcc生成静态库和动态库+静态库.a与.so库文件的生成与使用

概述:简单介绍静态库和动态库,根据提供的《用 gcc 生成 .a 静态库和 .so 动态库》《Linux 下静态库.a 与.so 库文件的生成与使用》两个PDF文件进行实仿操作。

目录

一、用gcc生成静态库和动态库

1.静态库、动态库简介

(1)静态库

(2)动态库

2.Linux系统下实仿——Hello XXX!

3.思考:当静态库和动态库同名时,gcc 命令会使用哪个库文件

4.补充

二、Linux 下静态库.a 与.so 库文件的生成与使用——练习

1.编写文件

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

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


一、用gcc生成静态库和动态库

1.静态库、动态库简介

库是写好的现有的,成熟的,可以复用的代码。现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常。本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。库有两种:

静态库.a(win 系统下是lib)和动态库.so(win 系统下是.dll)。所谓静态、动态是指链接。无论静态库,还是动态库,都是由.o文件创建的。因此,我们必须将源程序通过gcc先编译成.o文件。

(1)静态库

静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库。

特点:

-静态库对函数库的链接是放在编译时期完成的

-程序在运行时与函数库无关

-浪费空间和资源

(2)动态库

动态库在程序编译时并不会被连接到目标代码中,而是在程序运行时才被载入,因此在程序运行时还需要动态库存在。

动态类库的名字一般是libxxx.so,动态函数库在编译的时候并没有被编译进目标代码中,程序执行到相关函数时才调用该函数库里的相应函数,因此动态函数库所产生的可执行文件比较小。

动态库编译时:

最主要的是GCC命令行的一个选项, -shared 该选项指定生成动态连接库, 例如:

g++ -shared -o libmyhello.so hello.o /*根据中间目标文件hello.o创建动态库文件libmyhello.so*/

特点:

-动态库把对一些库函数的链接载入推迟到程序运行的时期。

-可以实现进程之间的资源共享。(动态库也称为共享库)

-将一些程序升级变得简单。

2.Linux系统下实仿——Hello XXX!

(1) 编辑生成程序hello.h、hello.c、main.c

创建本次作业目录,输入命令 mkdir test1

进入目录,输入命令 cd test1

运用vim编辑器编写hello.h、hello.c、main.c三个文件,运用cat命令查看文件内容。上述步骤如下所示:

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

输入命令 gcc -c hello.c

运用ls命令查看是否已生成hello.o文件

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

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

 (4)在程序中使用静态库

法一:直接输入命令 gcc -o hello main.c -L. -lmyhello

法二:直接输入命令 gcc main.c libmyhello.a -o hello

法三:先生成main.o文件,输入命令 gcc -c main.c

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

(5)由.o文件创建动态库文件

输入命令gcc -shared -fPIC -o libmyhello.so hello.o  得到动态库文件 libmyhello.so

运用 ls 命令查看动态库文件是否生成

(6)在程序中使用动态库 

运行 gcc 命令  gcc -o hello main.c -L. -lmyhello 生成目标文件
输入命令 ./hello将出现一下报错

 

程序在运行时,会在/usr/lib /lib 等目录中查找需要的动态库文件。若找到,则载入动态库,否则将提示类似上述错误而终止程序运行。这时我们需要将文件 libmyhello.so 复制到目录 /usr/lib 中,输入以下命令
mv libmyhello.so /usr/lib
./hello
此时将出现一下错误,需要提升权限,输入命令 su root后重新执行上述命令,程序运行成功,进一步说明 了动态库在程序运行时是需要的。

 

3.思考:当静态库和动态库同名时,gcc 命令会使用哪个库文件

(1)先删除除.c 和.h 外的所有文件,恢复成刚刚编辑完举例程序状态,依次输入以下命令

rm -f hello hello.o /usr/lib/libmyhello.so
ls

 

(2)创建静态库文件 libmyhello.a 和动态库文件 libmyhello.so,输入以下命令

 gcc -c hello.c                                                
 ar -cr libmyhello.a hello.o                           
 gcc -shared -fPIC -o libmyhello.so hello.o
 ls                                                                   
 
通过上述最后一条 ls 命令,可以发现静态库文件 libmyhello.a 和动态库文件 libmyhello.so 都已经生成,并都在当前目录中。
(3)运行 gcc 命令来使用函数库 myhello 生成目标文件 hello ,并运行程序 hello.输入以下命令:
  gcc -o hello main.c -L. –lmyhello
 ./hello
结果报错,如下图所示:

 

动态库和静态库同时存在时,优先使用动态库,当然,如果直接输入命令 gcc main.c libmyhello.a -o hello 的话,就是指定为静态库。 从程序 hello 运行的结果中很容易知道,当静态库和动态库同名时, gcc 命令将优先使用动态库,默认去连/usr/lib /lib 等目录中的动态库,将文件 libmyhello.so 复制到目录 /usr/lib 中即可。

4.补充

编译参数解析——主要的是 GCC 命令行的一个选项

命令解析
-shared
指定生成动态连接库, 相当于一个可执行文件。
-fPIC
表示编译为位置独立的代码,用于编译共享库。
-L.
表示要连接的库在当前目录中

 -lmyhello

编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上 lib ,后面加上.so .a 来确
定库的名称 libmyhello.so libmyhello.a

二、Linux 下静态库.a 与.so 库文件的生成与使用——练习

1.编写文件

(1)先创建一个作业目录,保存本次练习的文件。

mkdir test2
cd test2
(2) vim 文本编辑器编辑生成所需要的 四个文件 A1.c A2.c A.h、test.c 。
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", 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); 
}

用ls命令进行查看:

 

 

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

(1)输入以下命令生成目标文件(xxx.o)

         gcc -c A1.c A2.c

(2)生成静态库.a 文件

         ar crv libafile.a A1.o A2.o

(3)使用.a 库文件,创建可执行程序(若采用此种方式,需保证生成的.a 文件与.c 文件保

存在同一目录下,即都在当前目录下)
         
         gcc -o test test.c libafile.a
运行程序
         ./test

 

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

(1)生成目标文件(xxx.o) 此处生成.o 文件必须添加"-fpic"(小模式,代码少),否则在生成.so文件时会出错)

          gcc -c -fpic A1.c A2.c
(2)生成共享库 .so 文件
        gcc -shared *.o -o libsofile.so
(3)使用 .so 库文件,创建可执行程序
         gcc -o test test.c libsofile.so
         ./test
发现出现错误

 

运行 ldd test,查看链接情况

发现找不到对应的.so 文件。

这是由于 linux 自身系统设定的相应的设置的原因,即其只在 /lib and /usr/lib 下搜索对应的.so 文件,故需将对应 so 文件拷贝到对应路径。
     
      sudo cp libsofile.so /usr/lib
再次执行
   
       ./test
即可成功运行。

 


参考:

http://t.csdn.cn/i1d13

http://t.csdn.cn/prvOl
linux中动态库和静态库的区别是什么-linux运维-PHP中文网

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值