0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Linux中的静态库和共享库

嵌入式攻城狮 来源:嵌入式攻城狮 2023-05-10 09:34 次阅读

一. 什么是库

库是一个二进制文件,包含的代码可被程序调用。例如标准C库、数学库、线程库等等。库有源码,可下载后编译,也可以直接安装二进制包。 库是事先编译好的,可以复用的代码,在OS上运行的程序基本上都要使用库。使用库可以提高开发效率。Windows和Linux下库文件的格式不兼容。Linux下包含静态库和共享库。

二. 静态库

静态库有如下特点

编译(链接)时把静态库中相关代码复制到可执行文件中

程序中包含代码,运行时不再需要静态库

程序运行时无需加载库,运行速度更快

占用更多磁盘和空间

静态库升级后,程序需要重新编译链接

静态库的创建与链接参考如下步骤: 第一步:确定库中函数的功能、接口

第二步:编写库源码

/****hello.c****/
#include
#include"hello.h"

voidhello(void){
   printf("helloAndyxi
");
}
/****hello.h****/
#ifndef_HELLO_H_
#define_HELLO_H_

voidhello(void);

#endif

第三步:编译生成目标文件

linux@linux:~/andy/lib$ls
hello.chello.h
linux@linux:~/andy/lib$gcc-chello.c-Wall
linux@linux:~/andy/lib$ls
hello.chello.hhello.o

第四步:创建静态库

linux@linux:~/andy/lib$ls
hello.chello.hhello.o
linux@linux:~/andy/lib$arcrslibhello.ahello.o//使用arcrs命令创建静态库
linux@linux:~/andy/lib$ls
hello.chello.hhello.olibhello.a   //注意libhello.a是库文件名,hello是库名
linux@linux:~/andy/lib$nmlibhello.a   //使用nm命令可查看库中符号信息

hello.o:
00000000Thello
Uputs

第五步:编写应用程序

/****test.c****/
#include
#include"hello.h"

intmain(intargc,constchar*argv[]){
   hello();
return0;
}

第六步:编译应用程序并链接静态库

linux@linux:~/andy/lib$ls
hello.chello.hhello.olibhello.atest.c
linux@linux:~/andy/lib$gcc-otesttest.c-L.-l hello //使用-L.-l+库名链接静态库
linux@linux:~/andy/lib$ls
hello.chello.hhello.olibhello.atesttest.c
linux@linux:~/andy/lib$./test
helloAndyxi

由于使用的是静态库,编译后相关代码已经复制到可执行文件中。删除静态库,不影响程序执行

linux@linux:~/andy/lib$ls
hello.chello.hhello.olibhello.atesttest.c
linux@linux:~/andy/lib$rmlibhello.a
linux@linux:~/andy/lib$ls
hello.chello.hhello.otesttest.c
linux@linux:~/andy/lib$./test
helloAndyxi

三. 共享库

共享库有如下特点:

编译(链接)时仅记录用到哪个共享库中的哪个符号,不复制共享库中相关代码

程序不包含库中代码,尺寸小

多个程序可共享一个库

程序运行时需要加载库

库升级方便,无需重新编译程序

使用更加广泛

共享库的创建与链接参考如下步骤: 第一步:确定库中函数的功能、接口

第二步:编写库源码

/****hello.c****/
#include

voidhello(void){
   printf("helloworld
");
   return;
}
/****bye.c****/
#include

voidbye(void){
   printf("bye!
");
   return;
}
/****共享库头文件common.h****/
#ifndef__COMMON_H__
#define__COMMON_H__

voidhello(void);
voidbye(void);

#endif

第三步:编译生成目标文件

linux@linux:~/andy/lib/share$ls
bye.ccommon.hhello.c
linux@linux:~/andy/lib/share$gcc-c-fPIC*.c-Wall
linux@linux:~/andy/lib/share$ls
bye.cbye.ocommon.hhello.chello.o

fPIC选项:告诉编译器生成位置无关代码

位置无关代码:生成的".o文件"文件中的代码可以被加载到任意的地址执行。编译时用到了相对寻址而不是绝对寻址

第四步:创建共享库common

linux@linux:~/andy/lib/share$gcc-shared-olibcommon.so.1hello.obye.o
linux@linux:~/andy/lib/share$ls
bye.cbye.ocommon.hhello.chello.olibcommon.so.1

shared选项:告诉编译器生成一个共享库

生成的共享库的文件名叫"libcommon.so.1",其中".so"表示这是一个共享库,".1"表示这个库的版本是1

符号链接文件命名规则:lib<库名>.so

第五步:编写应用程序

/****test.c****/
#include
#include"common.h"

intmain(intargc,constchar*argv[]){
   hello();
   bye();
return0;
}

第六步:编译应用程序并链接共享库

#****为共享库文件创建链接文件****#
linux@linux:~/andy/lib/share$ls
bye.cbye.ocommon.hhello.chello.olibcommon.so.1test.c
linux@linux:~/andy/lib/share$ln-slibcommon.so.1libcommon.so //ln-s创建符号链接
linux@linux:~/andy/lib/share$ls
bye.cbye.ocommon.hhello.chello.olibcommon.solibcommon.so.1test.c

#****编译应用程序并链接共享库****#
linux@linux:~/andy/lib/share$gcc-otesttest.c-L.-lcommon
linux@linux-:~/andy/lib/share$ls
bye.cbye.ocommon.hhello.chello.olibcommon.solibcommon.so.1testtest.c

gcc -o test test.c -L. -lcommon:可见此处共享库和静态库用法相同;GCC在链接时首先找共享库,如果共享库不存在,则链接静态库,如果静态库也找不到,则报错

加"-static"选项后,编译器会直接去找静态库

共享库的加载:如果完成上述步骤后就执行程序,会报如下错误

linux@linux:~/andy/lib/share$./test
./test:errorwhileloadingsharedlibraries:libcommon.so:cannotopensharedobjectfile:Nosuchfileordirectory

出错原因:因为程序链接的是共享库,并没有复制共享库中的代码,程序在执行时会去加载用到的共享库,加载时会去缺省路径(比如"/lib","/usr/lib")下寻找共享库,但是我们创建的库在当前目录下,并不在系统库的搜索路径里,所以在执行时找不到共享库,因此报错

创建好共享库后还需要添加共享库加载路径

第七步:加载共享库并执行程序

linux@linux:~/andy/lib/share$exportLD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
linux@linux:~/andy/lib/share$./test
helloworld
bye!

export 用于将原来的环境变量导出

":"前面的"$LD_LIBRARY_PATH"是引用原先的值;":"后面的"."是追加了当前目录;还可追加其余共享库的路径,要用":"隔开

此方法是临时的,只对当前终端有效。当重新打开一个终端再执行改程序时又会报错

为了让系统能找到要加载的共享库,通常由三种方法:

把库拷贝到/usr/lib和/lib目录下

在LD_LIBRARY_PATH环境变量中添加库所在路径

添加/etc/ld.so.conf.d/*.conf文件,执行 ldconfig刷新

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Linux
    +关注

    关注

    87

    文章

    11279

    浏览量

    209264
  • 函数
    +关注

    关注

    3

    文章

    4326

    浏览量

    62553
  • 静态库
    +关注

    关注

    0

    文章

    21

    浏览量

    7426
  • 编译
    +关注

    关注

    0

    文章

    656

    浏览量

    32847
  • 共享库
    +关注

    关注

    0

    文章

    4

    浏览量

    5613

原文标题:Linux 中的静态库和共享库

文章出处:【微信号:嵌入式攻城狮,微信公众号:嵌入式攻城狮】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    动态静态的区别

    一、什么是本质上来说库是一种可执行代码的二进制形式,可以***作系统载入内存执行。二、的种类linux下的有两种:静态
    发表于 05-26 17:22

    Linux下动态静态的制作及使用

    可执行代码的二进制格式,可以被载入内存执行。根据链接时期的不同,又有:静态共享(动态
    发表于 11-18 17:05

    Linux静态和动态的制作与使用

    什么是静态函数库?动态函数又是什么?linux静态函数库是怎样创建并使用的?动态函数是怎样创建并使用的?
    发表于 04-26 06:45

    Linux系统共享编程

    一、说明 类似Windows系统的动态链接Linux也有相应的共享用以支持代码的复用
    发表于 09-13 16:49 24次下载

    Linux静态和动态共享)的制作与使用

    Linux静态和动态共享)的制作与使用Linux
    发表于 07-09 14:39 1167次阅读

    linux静态和动态分析

    的二进制是不兼容的。 本文仅限于介绍linux下的。 2.的种类 linux下的有两种:静态
    发表于 11-02 10:12 1次下载

    Linux静态元件资料合集免费下载

    本文档的主要内容详细介绍的是Linux静态元件资料合集免费下载
    发表于 12-28 17:04 6次下载

    你知道linux 静态共享

    静态链接和动态链接的区别在于,主程序在运行前,静态链接的链接固定写入在程序,而动态链接
    发表于 04-26 16:46 2894次阅读

    讲解Linux虚拟机之使用动态静态

    了解 Linux 如何使用,包括静态和动态的差别,有助于你解决依赖问题。
    发表于 05-06 17:05 2182次阅读
    讲解<b class='flag-5'>Linux</b>虚拟机之使用动态<b class='flag-5'>库</b>和<b class='flag-5'>静态</b><b class='flag-5'>库</b>

    C++基础语法知识之链接装载Linux共享

    Linux共享(Shared Library) Linux 下的共享就是普通的 ELF
    的头像 发表于 11-01 10:15 2897次阅读

    嵌入式Linux下动态静态使用

    以下主要介绍Linux 下动态静态、如何使用已有的动态, 以及如何制作一个动态
    发表于 11-01 16:57 1次下载
    嵌入式<b class='flag-5'>Linux</b>下动态<b class='flag-5'>库</b>和<b class='flag-5'>静态</b><b class='flag-5'>库</b>使用

    Linux下动态静态制作与调用

    静态是指在应用,有一些公共代码需要反复使用,就把这些代码编译为“”文件;在链接步骤,连接器将从
    的头像 发表于 08-24 15:03 3734次阅读
    <b class='flag-5'>Linux</b>下动态<b class='flag-5'>库</b>和<b class='flag-5'>静态</b><b class='flag-5'>库</b>制作与调用

    Linux开发_动态静态创建与Makefile规则

    介绍Linux静态、动态创建方式、完成静态、动态
    的头像 发表于 09-17 15:41 1248次阅读

    动态静态的制作步骤

    是一种可执行的二进制文件,是编译好的代码。使用可以提高开发效率。在 Linux 下有静态和动态
    的头像 发表于 07-27 11:00 799次阅读

    如何查看linux程序共享呢?

    linux系统,程序通常需要依赖于外部来正常工作。这些可以直接编译到程序,也可以从共享
    的头像 发表于 08-28 09:11 1582次阅读
    如何查看<b class='flag-5'>linux</b>程序<b class='flag-5'>共享</b><b class='flag-5'>库</b>呢?