问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

静态库和动态库的区别以及使用

发布网友 发布时间:2022-10-04 10:14

我来回答

1个回答

热心网友 时间:2023-10-14 06:50

  我们通常把一些公用函数制作成函数库,供其它程序使用。

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

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

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

  本文主要通过举例来说明在Linux中如何创建静态库和动态库,以及使用它们。

  在创建函数库前,我们先来准备举例用的源程序,并将函数库的源程序编译成.o文件。

  第1步:编辑得到举例的程序--hello.h、hello.c和main.c;

  hello.h(见程序1)为该函数库的头文件。

  hello.c(见程序2)是函数库的源程序,其中包含公用函数hello,该函数将在屏幕上输出"Hello XXX!"。

  main.c(见程序3)为测试库文件的主程序,在主程序中调用了公用函数hello。

  程序1: hello.h

  #ifndef HELLO_H

  #define HELLO_H

  void hello(const char *name);

  #endif //HELLO_H

  程序2: hello.c

  #include

  void hello(const char *name)

  {

  printf("Hello %s!/n", name);

  }

  程序3: main.c

  #include "hello.h"

  int main()

  {

  hello("everyone");

  return 0;

  }

  第2步:将hello.c编译成.o文件;

  无论静态库,还是动态库,都是由.o文件创建的。因此,我们必须将源程序hello.c通过gcc先编译成.o文件。

  在系统提示符下键入以下命令得到hello.o文件。

  # gcc -c hello.c

  #

  (注1:本文不介绍各命令使用和其参数功能,若希望详细了解它们,请参考其他文档。)

  (注2:首字符"#"是系统提示符,不需要键入,下文相同。)

  我们运行ls命令看看是否生存了hello.o文件。

  # ls

  hello.c hello.h hello.o main.c

  #

  (注3:首字符不是"#"为系统运行结果,下文相同。)

  在ls命令结果中,我们看到了hello.o文件,本步操作完成。

  下面我们先来看看如何创建静态库,以及使用它。

  第3步:由.o文件创建静态库;

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

  在系统提示符下键入以下命令将创建静态库文件libmyhello.a。

  # ar cr libmyhello.a hello.o

  #

  我们同样运行ls命令查看结果:

  # ls

  hello.c hello.h hello.o libmyhello.a main.c

  #

  ls命令结果中有libmyhello.a。

  第4步:在程序中使用静态库;

  静态库制作完了,如何使用它内部的函数呢?只需要在使用到这些公用函数的源程序中包含这些公用函数的原型声明,然后在用gcc命令生成目标文件时指明静态库名,gcc将会从静态库中将公用函数连接到目标文件中。注意,gcc会在静态库名前加上前缀lib,然后追加扩展名.a得到的静态库文件名来查找静态库文件。

  在程序3:main.c中,我们包含了静态库的头文件hello.h,然后在主程序main中直接调用公用函数hello。下面先生成目标程序hello,然后运行hello程序看看结果如何。

  # gcc -o hello main.c -L. -lmyhello

  # ./hello

  Hello everyone!

  #

  我们删除静态库文件试试公用函数hello是否真的连接到目标文件 hello中了。

  # rm libmyhello.a

  rm: remove regular file `libmyhello.a'? y

  # ./hello

  Hello everyone!

  #

  程序照常运行,静态库中的公用函数已经连接到目标文件中了。

  我们继续看看如何在Linux中创建动态库。我们还是从.o文件开始。

  第5步:由.o文件创建动态库文件;

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

  在系统提示符下键入以下命令得到动态库文件libmyhello.so。

  # gcc -shared -fPCI -o libmyhello.so hello.o

  #

  我们照样使用ls命令看看动态库文件是否生成。

  # ls

  hello.c hello.h hello.o libmyhello.so main.c

  #

  第6步:在程序中使用动态库;

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

  # gcc -o hello main.c -L. -lmyhello

  # ./hello

  ./hello: error while loading shared libraries: libmyhello.so: cannot open shared object file: No such file or directory

  #

  哦!出错了。快看看错误提示,原来是找不到动态库文件libmyhello.so。程序在运行时,会在/usr/lib和/lib等目录中查找需要的动态库文件。若找到,则载入动态库,否则将提示类似上述错误而终止程序运行。我们将文件 libmyhello.so复制到目录/usr/lib中,再试试。

  # mv libmyhello.so /usr/lib

  # ./hello

  Hello everyone!

  #

  成功了。这也进一步说明了动态库在程序运行时是需要的。

  我们回过头看看,发现使用静态库和使用动态库编译成目标程序使用的gcc命令完全一样,那当静态库和动态库同名时,gcc命令会使用哪个库文件呢?抱着对问题必究到底的心情,来试试看。

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

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

  # ls

  hello.c hello.h main.c

  #

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

  # gcc -c hello.c

  # ar cr libmyhello.a hello.o

  # gcc -shared -fPCI -o libmyhello.so hello.o

  # ls

  hello.c hello.h hello.o libmyhello.a libmyhello.so main.c

  #

  通过上述最后一条ls命令,可以发现静态库文件libmyhello.a和动态库文件libmyhello.so都已经生成,并都在当前目录中。然后,我们运行gcc命令来使用函数库myhello生成目标文件hello,并运行程序 hello。

  # gcc -o hello main.c -L. -lmyhello

  # ./hello

  ./hello: error while loading shared libraries: libmyhello.so: cannot open shared object file: No such file or directory

  #

  从程序hello运行的结果中很容易知道,当静态库和动态库同名时, gcc命令将优先使用动态库。
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
苹果电脑电池充不进电苹果电脑充不进去电是怎么回事 苹果电脑不充电没反应苹果电脑充电指示灯不亮充不了电怎么办 狗狗更加忠诚护家、善解人意,养一只宠物陪伴自己,泰迪能长多大... 描写泰迪狗的外形和特点的句子 国外留学有用吗 花钱出国留学有用吗 !这叫什么号 百万医疗赔付后是否可以续保 前一年理赔过医疗险还能续保吗? 医疗住院险理赔后还能购买吗? 导致肾结石的5大因素,需了解做好预防 浅谈多肉植物搭配花盆需要注意的几个细节 请问怎么查询一个网站是动态还是静态? huffman算法动态和静态的区别 养花插在花盆还要怎么做 有什么养花的技巧 花缸养花技巧和方法 花盆养花保活的五个技巧分享 求高手 速度解决 很感谢 填在空白处 老年人是否应接种加强针?权威回应 喝牛奶喝多了会怎么样,我一天三盒牛奶,250ml一盒? 产后抑郁可以持续多久,产后抑郁症连续复发了几次 一些产妇在生完宝宝搜得了产后忧郁症,恢复后还会再复发吗? 一些产妇在得了产后精神病治疗后,什么情况下会再复发? 自来卷头发应该怎么办 我的信用卡逾期了,请问有什么解决方法吗?网上的快速解决逾期的机构 能相信吗? 树菠萝籽的吃法技巧 树菠萝籽的吃法技巧有哪些 dior化妆品孕妇可以用吗? 口红迪奥999孕妇可以用吗 虚心问教,重度核辐射,中医如何救? 迪奥999口红孕妇可以使用吗 迪奥护肤品孕妇可以使用吗 成都市去黔南布依族苗族自治州游玩如何自驾? 之前逾期过6个月信用卡,现在读书交学费还可以分期付款吗? 雪中悍刀行第一季对应小说多少章 《雪中悍刀行》电视剧对应小说多少章? 暗区突围怎么不删微信扫码 暗区突围微信和qq可以一起玩吗 弟弟生日快乐祝福语 关于弟弟生日快乐的祝福语 八珍甜醋成都那儿有卖 三星手机和oppo手机哪个好 学期师德工作计划 简单不失华丽感咖啡金色眼妆 辣鸡脚最好吃的做法 辣鸡脚最好吃的制作方法 麻辣鸡脚的制作方法和配料 怎么做麻辣鸡脚 冰糖红果的做法,冰糖红果怎么做好吃,冰糖红果 黎麦长什么样图片 我以前用手机注册过,现在如何找回密码? 为什么苹果不能下载yumi 加味炒红果做法窍门 苹果上免费的交友软件有哪些呢 在日常生活中该怎么预防白癜风呢?