linux库引入之动态库静态库(生成和使用)

    科技2023-10-21  97

    库:

    库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。就是将源代码转化为二进制格式的源代码,相当于进行了加密,别人可以使用库,但是看不到库中的内容。

    如何使用 用户需要同时具有头文件和库。

    头文件(相当于说明书的作用,能够知道这个库能干嘛)

    制作出来的库(具体的实现,存放.c、.cpp)

    静态库: 是在程序执行前(编译)就加入到目标程序中去了。 优点: 1、静态库被打包到应用程序中运行速度快 2、发布程序无需提供静态库,因为已在app中,移植方便 缺点: 1、链接时完整的拷贝至可执行文件中,被多次使用就有多份冗余的拷贝。 2、更新、部署、发布、比较麻烦。 动态库: 是在执行程序时动态(临时)由目标程序去调用 优点: 1、链接时不复制,程序运行时由系统动态加载到内存,供程序使用,系统只加载一次,多个程序可以共用,节省内存。 2、程序升级简单,因为app里面没有源代码,升级之后只要库的名字不变,函数名以及参数不变,只是实现了优化,就能加载成功。 缺点: 1、加载速度比静态库慢 2、发布程序需要提供依赖的动态库

    静态库的制作和使用 (1)命名规则 静态库文件名的命名方式是“libxxx.a”,库名前加”lib”,后缀用”.a”,“xxx”为静态库名。 (2)制作步骤 原材料:源代码.c 或者 .cpp

    1、将.c文件生成.o,gcc a.c b.c -c

    pi@raspberrypi:~/test$ ls togetherfunc1.c togetherfunc1.h togetherfunc.c pi@raspberrypi:~/test$ gcc togetherfunc1.c -c pi@raspberrypi:~/test$ ls togetherfunc1.c togetherfunc1.h togetherfunc1.o togetherfunc.c

    2、将.o 打包 ar rcs 静态库的名字 原材料 ar rcs libtest.a a.o b.o

    pi@raspberrypi:~/test$ ar //输入指令ar,查看各个参数的功能 ps:以下是一些指令的介绍 mv togetherfunc1.c ~ //~表示工作目录 将这个.c文件移到工作目录 cp ~/togetherfunc1.c . //从工作目录再移到当前文件 mv togetherfunc1.* ~ //将当前文件夹下的以togetherfunc1开头的文件移动到工作目录下。 * 是通配符

    代码演示

    pi@raspberrypi:~/test$ ls togetherfunc1.c togetherfunc1.h togetherfunc1.o togetherfunc.c pi@raspberrypi:~/test$ ar rcs libfunc1.a togetherfunc1.o pi@raspberrypi:~/test$ ls libfunc1.a togetherfunc1.c togetherfunc1.h togetherfunc1.o togetherfunc.c

    (3)库的使用

    若直接-l 编译会报错,因为-l 会优先从/urs/lib 或 /urs/local/lib 中去找,但我们想让它优先从当前路径去找,就要用到-L。

    pi@raspberrypi:~/test$ gcc togetherfunc.c -lfunc1 /usr/bin/ld: cannot find -lfunc1 collect2: error: ld returned 1 exit status

    应该这样使用:

    gcc togetherfunc.c -lfunc1 -L ./ -o mainProstatic //-l 是指定要用的动态库名称,库名砍头去尾去掉lib和.a //-L 告诉gcc编译器从-L指定的路径去找静态库。默认先是从/urs/lib 或 /urs/local/lib 中去找,若-L后先从指定的路径去找,找不到再从/urs/lib 或 /urs/local/lib 中去找。 // ./表示当前路径 // -o后是编译后程序的名字

    动态库的生成和使用 (1)命名规则 动态库的命名方式与静态库类似,前缀相同,为“lib”,后缀变为“.so”。所以为“libmytime.so” (2)制作步骤

    输入指令:

    gcc -shared a.o b.o -o libxxx.so

    代码演示:

    pi@raspberrypi:~/test $ ls libfunc1.a togetherfunc1.c togetherfunc1.h pi@raspberrypi:~/test $ gcc -shared -fpic togetherfunc1.c -o libfun1.so pi@raspberrypi:~/test $ ls libfun1.so libfunc1.a togetherfunc1.c togetherfunc1.h //-shared 的意思是指定生成动态库 // -fpic 标准,fpic选项作用于编译阶段,在生成目标文件时就得使用该选项,以生成位置无关的代码。

    (3)动态库的使用

    动态库优先从当前路径去找,没找到的话再去/usr/lib/下去找

    sudo cp libfun2.so /usr/lib/ //将生成的动态库拷贝到/usr/lib sudo rm /usr/lib/libfun2.so //从/usr/lib/中移除刚才移入的动态库 gcc togetherfunc.c -l fun2 -L ./ -o mianPrody //这是编译的时候 //运行的时候可能此时会提示No such file or directory,需要进行环境变量的设置

    动态库无法加载(引用动态库,怎么指定动态库的位置):

    临时设置: 在终端进行: export LD_LIBRARY_PATH=“动态库的路径”

    利用脚本:

    vi start.sh //创建一个.sh文件 export LD_LIBRARY_PATH="/home/pi/test//动态库的路径" ./mianPrody//所要执行的程序名称 //在文件夹中输入以上内容 chmod +x start.sh //给脚本加可执行的的权限 ./start.sh //执行该脚本

    计算文件大小

    pi@raspberrypi:~/test $ du libfunc1.a 4 libfunc1.a pi@raspberrypi:~/test $ du mianPrody 12 mianPrody
    Processed: 0.009, SQL: 9