浅析linux共享库的使用

通过最基本的一个头文件、一个函数文件、一个主调文件fun.h,fun.c,main.c来练习动态库与静态库的使用,整理如下:

编辑源代码

头文件:fun.h

#ifndef FUN_H   //通过编译预处理命令避免头文件被多次包含


#define FUN_H


#include <stdio.h>


typedef int T; //为类型定义一个别名,如果需要用其他类型只要在此处更改即可


//声明加减乘除的各个函数

T add(T a,T b);


T sub(T a,T b);


T mul(T a,T b);


T div(T a,T b);


#endif


函数文件:fun.c


#include "fun.h"

//实现两个数的加减乘除
T add(T a,T b) //two number addition
{
        return a+b;
}


T sub(T a,T b) //two number subtraction 
{
        return a-b;
}


T mul(T a,T b) //two number multiply
{
        return a*b;
}


T div(T a,T b) //two number division
{
        return a/b;
}

主函数文件:main.c

#include "fun.h"


int main()
{
        int a=10,b=5;


        printf("add:%d\n",add(a,b));


        printf("sub:%d\n",sub(a,b));


        printf("mul:%d\n",mul(a,b));


        printf("div:%d\n",div(a,b));


}


生成目标文件

# gcc -c fun.c 

无论静态库,还是动态库,都是由.o文件创建的。因此,我们必须将源程序通过gcc先编译成.o文件。

查看详细信息:

#ll

total 32
drwxr-xr-x 2 root root 4096 2013-05-16 03:04 ./
drwxr-xr-x 3 root root 4096 2013-05-15 21:25 ../
-rw-r--r-- 1 root root  162 2013-05-16 01:21 \
-rw-r--r-- 1 root root  233 2013-05-16 02:36 fun.c
-rw-r--r-- 1 root root   96 2013-05-16 01:12 fun.cpp
-rw-r--r-- 1 root root  134 2013-05-16 01:40 fun.h
-rw-r--r-- 1 root root  779 2013-05-16 03:04 fun.o
-rw-r--r-- 1 root root  167 2013-05-16 01:39 main.c

可以看到生成了fun.o文件


生成静态库

在linux下,库文件一般放在/usr/lib、/lib下,本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行

静态库的名字一般为libxxxx.a,其中xxxx是该lib的名称

动态库的名字一般为libxxxx.so.major.minor,xxxx是该lib的名称,major是主版本号, minor是副版本号

共享库的好处是,不同的应用程序如果调用相同的库,那么在内存里只有一份该共享库的实例,有助于节省内存,有助于资源共享,简化了软件项目的管理.

静态库文件通过ar命令来创建,动态库文件通过gcc -shared -fpic -o libxxx.so xxx.o来创建

# ar -r libmyku.a fun.o 
ar: creating libmyku.a


#ll

total 36
drwxr-xr-x 2 root root 4096 2013-05-16 03:09 ./
drwxr-xr-x 3 root root 4096 2013-05-15 21:25 ../
-rw-r--r-- 1 root root  162 2013-05-16 01:21 \
-rw-r--r-- 1 root root  233 2013-05-16 02:36 fun.c
-rw-r--r-- 1 root root   96 2013-05-16 01:12 fun.cpp
-rw-r--r-- 1 root root  134 2013-05-16 01:40 fun.h
-rw-r--r-- 1 root root  779 2013-05-16 03:04 fun.o
-rw-r--r-- 1 root root  944 2013-05-16 03:09 libmyku.a
-rw-r--r-- 1 root root  167 2013-05-16 01:39 main.c

可以看到生成了静态库文件libmyku.a


使用静态库

先看一下不使用库的编译运行结果:

# gcc main.c fun.c
# ll
total 44
drwxr-xr-x 2 root root 4096 2013-05-16 03:11 ./
drwxr-xr-x 3 root root 4096 2013-05-15 21:25 ../
-rw-r--r-- 1 root root  162 2013-05-16 01:21 \
-rwxr-xr-x 1 root root 7278 2013-05-16 03:11 a.out*
-rw-r--r-- 1 root root  233 2013-05-16 02:36 fun.c
-rw-r--r-- 1 root root   96 2013-05-16 01:12 fun.cpp
-rw-r--r-- 1 root root  134 2013-05-16 01:40 fun.h
-rw-r--r-- 1 root root  779 2013-05-16 03:04 fun.o
-rw-r--r-- 1 root root  944 2013-05-16 03:09 libmyku.a
-rw-r--r-- 1 root root  167 2013-05-16 01:39 main.c
# ./a.out 
add:15
sub:5
mul:50
div:2

下面再看一下使用静态库编译运行的结果:

# gcc -o smain main.c  libmyku.a   

或者通过-L 、-l、参数指定路径与库名来连接:

# gcc -o smain main.c -L. -lmyku

# ll
total 52
drwxr-xr-x 2 root root 4096 2013-05-16 03:20 ./
drwxr-xr-x 3 root root 4096 2013-05-15 21:25 ../
-rw-r--r-- 1 root root  162 2013-05-16 01:21 \
-rwxr-xr-x 1 root root 7278 2013-05-16 03:11 a.out*
-rw-r--r-- 1 root root  233 2013-05-16 02:36 fun.c
-rw-r--r-- 1 root root   96 2013-05-16 01:12 fun.cpp
-rw-r--r-- 1 root root  134 2013-05-16 01:40 fun.h
-rw-r--r-- 1 root root  779 2013-05-16 03:04 fun.o
-rw-r--r-- 1 root root  944 2013-05-16 03:09 libmyku.a
-rw-r--r-- 1 root root  167 2013-05-16 01:39 main.c
-rwxr-xr-x 1 root root 7278 2013-05-16 03:20 smain*

# ./smain 
add:15
sub:5
mul:50
div:2

静态库的代码在编译过程中载入可执行程序,因此体积与不使用库一样大。


生成动态库

# gcc -shared -fpic -o libmyku.so fun.o 
root@ubuntu:/home/psh/uc/day01# ll
total 60
drwxr-xr-x 2 root root 4096 2013-05-16 04:36 ./
drwxr-xr-x 3 root root 4096 2013-05-15 21:25 ../
-rw-r--r-- 1 root root  162 2013-05-16 01:21 \
-rwxr-xr-x 1 root root 7278 2013-05-16 04:32 a.out*
-rw-r--r-- 1 root root  235 2013-05-16 04:32 fun.c
-rw-r--r-- 1 root root   96 2013-05-16 01:12 fun.cpp
-rw-r--r-- 1 root root  134 2013-05-16 01:40 fun.h
-rw-r--r-- 1 root root  779 2013-05-16 03:04 fun.o
-rw-r--r-- 1 root root  944 2013-05-16 04:35 libmyku.a
-rwxr-xr-x 1 root root 6694 2013-05-16 04:36 libmyku.so*
-rw-r--r-- 1 root root  186 2013-05-16 04:17 main.c
-rwxr-xr-x 1 root root 7278 2013-05-16 04:36 smain*

使用动态库

# gcc -o dmain main.c libmyku.so 
# ll
total 68
drwxr-xr-x 2 root root 4096 2013-05-16 04:40 ./
drwxr-xr-x 3 root root 4096 2013-05-15 21:25 ../
-rw-r--r-- 1 root root  162 2013-05-16 01:21 \
-rwxr-xr-x 1 root root 7278 2013-05-16 04:32 a.out*
-rwxr-xr-x 1 root root 7272 2013-05-16 04:40 dmain*
-rw-r--r-- 1 root root  235 2013-05-16 04:32 fun.c
-rw-r--r-- 1 root root   96 2013-05-16 01:12 fun.cpp
-rw-r--r-- 1 root root  134 2013-05-16 01:40 fun.h
-rw-r--r-- 1 root root  779 2013-05-16 03:04 fun.o
-rw-r--r-- 1 root root  944 2013-05-16 04:39 libmyku.a
-rwxr-xr-x 1 root root 6694 2013-05-16 04:36 libmyku.so*
-rw-r--r-- 1 root root  186 2013-05-16 04:17 main.c
-rwxr-xr-x 1 root root 7278 2013-05-16 04:36 smain*

生成可执行文件成功,由于动态库文件是在可执行文件运行时才加载到内存中,因此生成的可执行文件相对会比较小,由于程序很简单,此处不明显,下面执行一下:

# ./dmain 
./dmain: error while loading shared libraries: libmyku.so: cannot open shared object file: No such file or directory

提示加载共享库文件失败,找不到共享库文件

为了让可执行文件顺利找到共享库文件,有以下三种方法:

(1)把共享库文件拷贝到/usr/lib或者/lib目录下,有效性是全局的

#cp libmyku.so /usr/lib

(2修改/etc/ld.so.conf文件,把库所在的路径加到文件的末尾,并执行ldconfig命令刷新,这样,加入的目录正反库都可见

  (3)改变环境变量,在LD_LIBRARY_PATH环境变量中加上库所在路径(当前目录"."),只对当前shell终端有效


# LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.  

# ./dmain 

add:15
sub:5
mul:50
div:2

OK,可以了。
--------------------------------全文完-----------------------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值