Linux静态函数库与动态函数库讲解 您所在的位置:网站首页 linux查看动态库中的函数 Linux静态函数库与动态函数库讲解

Linux静态函数库与动态函数库讲解

2022-03-26 20:10| 来源: 网络整理| 查看: 265

编译mymath.C为mymath.o

[jiang@eb50 43]$ g++ -c mymath.C

生成静态库,只包含一个mymath.o文件

[jiang@eb50 43]$ ar rcs mymath.a mymath.o

编译生成目标文件main

[jiang@eb50 43]$ g++ -o main main.C mymath.a [jiang@eb50 43]$ ll 总计 32 -rwxrwxr-x 1 jiang jiang 8912 10-16 19:00 main -rw-rw-r-- 1 jiang jiang 115 10-16 18:43 main.C -rw-rw-r-- 1 jiang jiang 1840 10-16 19:00 mymath.a -rw-rw-r-- 1 jiang jiang 181 10-16 18:58 mymath.C -rw-rw-r-- 1 jiang jiang 119 10-16 18:34 mymath.h -rw-rw-r-- 1 jiang jiang 1656 10-16 19:00 mymath.o [jiang@eb50 43]$ ./main 32

关于ar的选项(rcs)可以参见(man ar):

r:Insert the files member… into archive (with replacement). c:Create the archive. s:Write an object-file index into the archive, or update an existing one, even if no other change is made to the archive.

更多ar选项还请参见man手册.

动态函数库:

.so动态函数库可以在程序启动时加载,也可以在程序中使用dlopen等操作动态地在程序运行中进行加载.

动态链接库与普通的程序相比而言,没有main函数,是一系列函数的实现.

动态函数库的名字:

通常约定,一个mymath的动态库的名字应当是:

libmymath.so[版本号]

lib+动态苦命+.so+版本信息

可以在/usr/lib中看到类似下面的很多软链接:

lrwxrwxrwx 1 root root 26 2013-03-13 libssl.so -> ../../lib/libssl.so.0.9.8e

我们倒着来:

我们要是用库ssl,应该在链接的时候加上-lssl;

链接器看到-lssl,就知道要找一个库叫做libssl.so的库文件(或软链接);

ssl库在哪里呢?通常编译时刻是由-L来决定查找的路径;

找到了libssl.so发现是个软链接,实际指向另一个库(../../lib/libssl.so.0.9.8e).

看到了吗?libssl.so指向的文件名叫做:libssl.so.0.9.8e.

对比下上面的格式:

0.9.8e就是版本信息.

也就是说,我们常用的是个软链接,叫做libxxx.so,然后实际指向一个带版本信息的真实的库文件.

怎样创建动态程序库?

实例:

描述:希望构建一个libmymath.so,包含基本运算.

mymath.h

#ifndef _MYMATH_H #define _MYMATH_H int add(int, int); int sub(int, int); int mul(int, int); int dev(int, int); #endif

mymath.C

#include "mymath.h" int add(int a, int b) { return a + b; } int sub(int a, int b) { return a - b; } int mul(int a, int b) { return a * b; } int dev(int a, int b) { return a / b; }

main.C

#include #include "mymath.h" using namespace std; int main() { cout libmymath.so.1 -rwxrwxr-x 1 jiang jiang 8231 10-16 19:40 libmymath.so.1 -rw-rw-r-- 1 jiang jiang 115 10-16 19:39 main.C -rw-rw-r-- 1 jiang jiang 181 10-16 18:58 mymath.C -rw-rw-r-- 1 jiang jiang 119 10-16 18:34 mymath.h -rw-rw-r-- 1 jiang jiang 4856 10-16 19:40 mymath.o

使用动态库(编译时):

[jiang@eb50 43]$ g++ -o main main.C -L $PWD -lmymath

运行目标程序:

[jiang@eb50 43]$ ll 总计 44 lrwxrwxrwx 1 jiang jiang 14 10-16 19:40 libmymath.so -> libmymath.so.1 -rwxrwxr-x 1 jiang jiang 8231 10-16 19:40 libmymath.so.1 -rwxrwxr-x 1 jiang jiang 8804 10-16 19:42 main -rw-rw-r-- 1 jiang jiang 115 10-16 19:39 main.C -rw-rw-r-- 1 jiang jiang 181 10-16 18:58 mymath.C -rw-rw-r-- 1 jiang jiang 119 10-16 18:34 mymath.h -rw-rw-r-- 1 jiang jiang 4856 10-16 19:40 mymath.o [jiang@eb50 43]$ ./main ./main: error while loading shared libraries: libmymath.so: cannot open shared object file: No such file or directory

出错了.

先暂时放下最后的错误,这里有几个需要注意的地方:

1.编译生成.o文件时使用了-fPIC选项,指代:Position Independent Code; 2.由众多.o文件构建成.so是使用-shared; 3.ln -s其实不是必要的,准确的说,你可以由步骤2生成一个libmymath.so不带版本号,也就不用软链接再次链接了; 4.编译目标程序时,-L指明在哪些目录中查找,-l指明要寻找的库; 注:如果-lxxx,则要在-L指明的库中查找libxxx.so这个文件,它可能是个软链接,也可能是个实际的库文件;

好了,现在解决最后的运行出的问题。

我们可以先用ldd查看main这个可执行文件与哪些动态库有关系:

[jiang@eb50 43]$ ldd main linux-vdso.so.1 => (0x00007fff077fd000) libmymath.so => not found libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x0000003a53600000) libm.so.6 => /lib64/libm.so.6 (0x0000003a41800000) libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x0000003a51a00000) libc.so.6 => /lib64/libc.so.6 (0x0000003a41000000) /lib64/ld-linux-x86-64.so.2 (0x0000003a40800000)

(ldd prints the shared libraries required by each program or shared library specified on the command line.)

我们发现libmymath.so没找到,这是为啥呢?

原来在ldd/运行时,并不是从-L(实际上也没有这个-L)中查找:

-L是gcc/g++在编译时刻的选项,指明从哪些目录中查找动态库文件;

运行时刻的库加载(搜索)由当前shell的环境变量LD_LIBRARY_PATH决定;

[jiang@eb50 43]$ export LD_LIBRARY_PATH=. [jiang@eb50 43]$ ldd main linux-vdso.so.1 => (0x00007fff912a6000) libmymath.so => ./libmymath.so (0x00002b0ad452b000) libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x0000003a53600000) libm.so.6 => /lib64/libm.so.6 (0x0000003a41800000) libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x0000003a51a00000) libc.so.6 => /lib64/libc.so.6 (0x0000003a41000000) /lib64/ld-linux-x86-64.so.2 (0x0000003a40800000) [jiang@eb50 43]$ ./main 22

当然,你可以给LD_LIBRARY_PATH一个绝对路径,而不是一个”.”(相对路径).

还有一种动态程序库使用的方式是使用dlopen系列函数来操作,这个后续再进行介绍.

(10,>


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有