Linux库的制作和使用

本文介绍了Linux下静态库和动态库的概念、特点、制作及使用方法。静态库在链接时会被整合到可执行文件中,运行速度快但体积大;动态库在运行时加载,节省空间但需要管理。详细讲解了如何创建静态库(*.a)和动态库(*.so),以及如何在程序中使用这些库。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

编译一个程序为可执行文件时,需要经过四部曲 : 预处理、编译、汇编、链接
在这里插入图片描述

而库是二进制形式目标模块的包,是多个目标模块(xxx.o)的集合

当使用库时,在链接阶段可以将库链接进可执行程序,同时也可以链接目标模块

库的概念

库是一个二进制文件,包含的代码可被程序调用(标准C库、数学库、线程库…)
库有源码,可下载后编译;也可以直接安装二进制包
系统中一般默认库的安装路径:/lib 、 /usr/lib

库是事先编译好的,可以复用的代码。
在OS上运行的程序基本上都要使用库,使用库可以提高开发效率。
Windows和Linux下库文件的格式不兼容
Linux下包含静态库和共享库(动态库)

静态库(*.a)

特点

  • 链接阶段被加载到目标文件中
  • 程序运行时不需要加载静态库,运行速度快
  • 编译后的可执行程序体积较大
  • 静态库升级后,程序需要重新编译链接

制作

  • 确定库中函数的功能接口

  • 编译库源码hello.c

#include <stdio.h>
void hello(void){
   printf("hello world\n");
   return ;
}
  • 编译生成目标文件
    gcc -c hello.c -Wall

  • 将目标文件打包成静态库(库名的前缀必须是lib)
    ar crs libhello.a hello.o

使用

  • 编写应用程序test.c
#include <stdio.h>

void hello(void);
int main(){
	hello();
	return 0;
}
  • 编译test.c 并链接静态库libhello.a
    gcc -o test test.c -L. -lhello
    注:-l表示链接哪个库名-L表示库的额外搜索路径(相对路径或者绝对路径),例如在当前目录下时用“-L.”表示,在当前目录下的lib文件夹中用“-L./lib”

在这里插入图片描述

共享(动态)库(*.so)

特点

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

  • 程序不包含库中代码,尺寸小
  • 多个程序可共享同一个库
  • 程序运行时需要加载库
  • 升级方便无需要重新编译程序

制作

  • 确定库中函数的功能接口

  • 编译库源码hello.c bye.c

#include <stdio.h>
void hello(void)
{
	printf("hello world\n");
	return ;
}
#include <stdio.h>
void bye(void)
{
	printf("bye!\n");
	return ;
}
  • 编译生成目标文件
    gcc -c -fPIC hello.c bye.c -Wall(-fPIC:必须编译选项,表示生成位置无关代码 概念上就是在可执行程序装载它们的时候,它们可以放在可执行程序的内存里的任何地方。 )

  • 创建共享库 common
    gcc -shared -o libcommon.so.1 hello.o bye.o

  • 为共享库文件创建链接文件
    ln -s libcommon.so.1 libcommon.so

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

使用

  • 编写应用程序test.c
#include <stdio.h>
#include "common.h"

int main(){
	hello();
	bye();
	return 0;
}
  • 编译test.c 并链接共享库libcommon.so
    gcc -o test test.c -L. -lcommon
    注:-l表示链接哪个库名-L表示库的额外搜索路径(相对路径或者绝对路径),例如在当前目录下时用“-L.”表示,在当前目录下的lib文件夹中用“-L./lib”

注意⚠️:当静态库和动态库同名,优先使用动态库
使用动态库时,分两种加载方法,分别是静态加载和动态加载
静态加载就是程序一运行, 就自动加载
动态加载就是程序运行中,由程序猿的代码控制加载

此时还不能立即,因为在动态函数库使用时,会查找/usr/lib /lib目录下的动态函数库,而此时我们生成的库不在里边,我们要加载共享库。

加载共享库

添加共享库的加载路径
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
在这里插入图片描述

如何找到共享库

运行时要让执行程序顺利找到动态库,有三种方法 :

  1. 把库拷贝到/usr/lib和/lib目录下(不建议)

  2. 在LD_LIBRARY_PATH环境变量中加上库所在路径。 //对当前的shell,临时生效
    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.

  3. 修改/etc/ld.so.conf文件,把库所在的路径加到文件末尾,并执行sudo ldconfig刷新。

    /etc/ld.so.conf是非常重要的一个目录,里面存放的是链接器和加载器搜索共享库时要检查的目录,默认是从/usr/lib /lib中读取的,所以想要顺利运行,我们也可以把我们库的目录加入到这个文件中并执行/sbin/ldconfig。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值