浅谈linux - 库文件制作与使用

概述 

本质上来说,库文件就是可执行代码的二进制形式,可以被操作系统载入内存中执行。

Linux操作系统支持的函数库分为静态库和动态库,动态库又称共享库。

Linux系统有几个重要的目录存放相应的函数库,如/lib、/usr/lib。

注意

静态库

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

特点

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

2、程序运行时无需加载,运行速度更快。

3、需要占用更多的磁盘和内存空间。

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

动态库

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

特点

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

2、多个程序可共享同一个库。

3、程序运行时需要加载库。

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

5、使用更加广泛。

另外,小编所有文章均是自己亲手编写验证,由于文件太多,小编就不在公众号后台一一回复列举了,若需要小编的工程代码,请关注公众号,后台回复需要的工程文件。小编看到后会第一时间回复。

操作

静态库

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

d7e7bb318cc8b529c93f6a6272507dc2.png

编写库源码

478775a4af8c6382f515e69b0e5484a4.png

编译生成目标文件:cc -c opr.c -Wall

3cf02d7a1f936e0df5622c154fc329e2.png

创建静态库:ar crs libopr.a opr.o

注意:linux生成静态库文件名称必须以lib开始.a结尾

b1789c74a4b7176dfb0d3055ff494031.png

检查库,查看库中符号信息:nm libopr.a

c2111a1aa2f4b159525630ce19249088.png

编写应用程序,调用库

0c0f92b657eb3774abc54d1f96e2f357.png

编译应用程序并链接静态库:gcc -o main main.c -L. -lopr

注意:-L告诉编译器库的路径,-l后面指定库的名称。

编译器默认链接C库,如果库本身就放在C库下,就不需要指定路径,否则必须指定路径。

a4e507183a4e690bd5a2fec8be46f74d.png

运行应用程序:./main

239e9bf5931477a4a436a69376777058.png

动态库

确定库汇总函数的功能、接口

061d42f87ef3addeb5163cc2559c9890.png

编写库源码

1b457bbb117735f5561bf43eab660752.png

编译生成目标文件:gcc -c -fPIC opr.c -Wall

注意:-fPIC告诉编译器生成位置无关代码。

a9f063f14a2b2d09f39cee0a7973141a.png

编译生成共享库:gcc -shared -o libopr.so.1 opr.o

注意:共享库命名规则:以lib开始,.so结尾,后面可加上数字表示共享库不同版本号。

1308d5f3783afc8d5aa55a92061a41be.png

为共享库创建符号链接:ln -s libopr.so.1 libopr.so

注意:符号链接名称后面不能跟版本号

daa6041f58c2333676259ff3fabd9367.png

编写应用程序。

2d417ea08d0c09254d379dea8de34b48.png

编译应用程序并链接共享库:gcc -o main main.c -L. -lopr

注意:跟链接静态库一样,对于gcc来说,编译器首先寻找共享库,如果共享库找不到再链接静态库,若想直接找静态库可以加-static选项。

ebfaf62d9740cacc96b1455610fb71f7.png

添加共享库的加载路径,并执行应用程序。

方法一:通过修改环境变量。export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.

注意:方法一只对当前sheel有效(临时有效,最简单)。

5460011463956cb5202824ca0dedb793.png

方法二:将库拷贝到/usr/lib和lib目录下(不太建议)。

方法三:将库路径加入配置文件中

步骤一:新建配置*.conf文件:sudo vi /etc/ld.so.conf.d/feng.conf

4bcf3417134497c76add2046bd83e23f.png

步骤二:输入库文件所在目录路径:/home/feng/feng/library/dynamic

4dde3097cd396b7bc567e56f6a85bd92.png

步骤三:执行ldconfig刷新:sudo ldconfig。

1f0bd76bb9cf69b0732c7fd8b923e85d.png

步骤四:运行应用程序。

ee9228dcaa40d347b8bffa77b6af82bf.png

示例

★包含演示程序库文件源码opr.c、头文件opr.h以及应用程序main.c(已验证通过)。

1db1efbdb93cc84308acf6da6c10821d.png opr.h

/**
 * @Filename : opr.h
 * @Revision : $Revision: 1.00 $
 * @Author : Feng(更多编程相关的知识和源码见微信公众号:不只会拍照的程序猿,欢迎订阅)
 * @Description : linux库测试
**/

#ifndef __OPR_H__
#define __OPR_H__

/**
 * 加法处理
 * @ a,b操作数
 * 返回结果
*/
int add(int a, int b);

/**
 * 减法处理
 * @ a,b操作数
 * 返回结果
*/
int sub(int a, int b);

/**
 * 乘法处理
 * @ a,b操作数
 * 返回结果
*/
int mul(int a, int b);

#endif

2d4bb4c852b747a044bee25311056378.png opr.c

/**
 * @Filename : opr.c
 * @Revision : $Revision: 1.00 $
 * @Author : Feng(更多编程相关的知识和源码见微信公众号:不只会拍照的程序猿,欢迎订阅)
 * @Description : linux库测试
**/

#include "opr.h"

/**
 * 加法处理
 * @ a,b操作数
 * 返回结果
*/
int add(int a, int b)
{
    return (a + b);
}

/**
 * 减法处理
 * @ a,b操作数
 * 返回结果
*/
int sub(int a, int b)
{
    return (a - b);
}

/**
 * 乘法处理
 * @ a,b操作数
 * 返回结果
*/
int mul(int a, int b)
{
    return (a * b);
}

0bfc0ddfcd1c07232673f59ef59016b8.png main.c

/**
 * @Filename : main.c
 * @Revision : $Revision: 1.00 $
 * @Author : Feng(更多编程相关的知识和源码见微信公众号:不只会拍照的程序猿,欢迎订阅)
 * @Description : linux库测试,应用程序
**/

#include "opr.h"
#include <stdio.h>

int main(void)
{
    int a=10, b=2;

    printf("%d + %d = %d\n", a, b, add(a, b));
    printf("%d - %d = %d\n", a, b, sub(a, b));
    printf("%d * %d = %d\n", a, b, mul(a, b));

    return 0;

往期 · 推荐

实时系统vxWorks - 任务(重要)

实时系统vxWorks - 加载应用程序的方法

实时系统vxWorks - 在线调试

实时系统vxWorks - 虚拟机环境搭建

实时系统vxWorks - zynq7020移植vxWorks

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不只会拍照的程序猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值