参考文章:dll和so文件区别与构成:http://www.cnblogs.com/likwo/archive/2012/05/09/2492225.html

动态库路径配置- /etc/ld.so.conf文件:http://blog.csdn.net/blade2001/article/details/32839937

1.如何生成一个动态库:

假设有4个文件(1个头文件,3个.c源文件)so_test.h、test_a.c、test_b.c、test_c.c。我们将这几个文件编译成一个动态库:libtest.so。

so_test.h:
 
#include <stdio.h>
#include <stdlib.h>
void test_a();
void test_b();
void test_c();
 
test_a.c:
 
#include "so_test.h"
void test_a()
{
    printf("this is in test_a...\n");
}
 
test_b.c:
 
#include "so_test.h"
void test_b()
{
    printf("this is in test_b...\n");
}
 
test_c.c:
 
#include "so_test.h"
void test_c()
{
    printf("this is in test_c...\n");
}
 
将这几个文件编译成一个动态库:libtest.so
$ gcc test_a.c test_b.c test_c.c -fPIC -shared -o libtest.so
2、动态库的链接
 
在1、中,我们已经成功生成了一个自己的动态链接库libtest.so,下面我们通过一个程序来调用这个库里的函数。程序的源文件为:test.c。
test.c:
 
#include "so_test.h"
int main()
{
    test_a();
    test_b();
    test_c();
    return 0;
 
}
l         将test.c与动态库libtest.so链接生成执行文件test:
$ gcc test.c -L. -ltest -o test
 
l         测试是否动态连接,如果列出libtest.so,那么应该是连接正常了
 
$ ldd test
l         执行test,可以看到它是如何调用动态库中的函数的。
但是此时出现以下问题:

$>ldd test
linux-gate.so.1 => (0xb77c6000)
libtest.so => not found//动态库未找到
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb75ea000)
/lib/ld-linux.so.2 (0xb77c7000)

但是查看当前目录下明明有动态库呀。

$>ls -l
总用量 36
-rwxrwxr-x 1 burgess burgess 6992 Dec 6 16:58 libtest.so
-rw-rw-r-- 1 burgess burgess 249 Dec 6 16:54 so_test.h
-rwxrwxr-x 1 burgess burgess 7372 Dec 6 17:00 test
-rw-rw-r-- 1 burgess burgess 189 Dec 6 16:55 test_a.c
-rw-rw-r-- 1 burgess burgess 189 Dec 6 16:56 test_b.c
-rw-rw-r-- 1 burgess burgess 209 Dec 6 17:00 test.c
-rw-rw-r-- 1 burgess burgess 189 Dec 6 16:57 test_c.c

执行./test却出错!

./test
./test: error while loading shared libraries: libtest.so: cannot open shared object file: No such file or directory

错误提示动态库里没有这个文件。

动态装入器负责装入动态链接的可执行程序运行所需的共享库(shared library,即动态库)。

ld.so.conf 文件包含一个所有目录(/lib 和 /usr/lib 除外,它们会自动包含在其中)的清单,动态装入器将在其中查找共享库。

那么此时我们就需要把这个文件的路径加入ld.so.conf 文件里了。

最省事的办法就是通过/etc/ld.so.conf文件来指定动态库的目录(需要有root权限)。

#vi  /etc/ld.so.conf

里面显示:

include /etc/ld.so.conf.d/*.conf
 /usr/local/lib

这里的“/usr/local”就是默认的动态库路径了。我们想要添加自己的路径再起一行加入就OK。j假设“libtest.so”所在路径是:“/home/burgess/gitlearn/test”

那么添加进去就变成了

include /etc/ld.so.conf.d/*.conf
 /usr/local/lib
/home/burgess/gitlearn/test

但是加进去了,退回到当前用户再去$>ldd test还是显示libtest.so => not found。

原来在动态装入器能“看到”这一信息之前,必须将它转换到 ld.so.cache 文件中。可以通过运行 ldconfig 命令做到这一点:

#ldconfig

另外,要查看 ldconfig 可以“看到”的所有共享库,输入:  

# ldconfig -p | less

就可以查看libtest.so是否在显示的库列表里了。

最后,再执行:

$>ldd test

显示动态库就找到了:

linux-gate.so.1 => (0xb77dc000)
libtest.so => /home/burgess/gitlearn/test/libtest.so (0xb77b8000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb75fd000)
/lib/ld-linux.so.2 (0xb77dd000)

(下面这段话是照第二篇文章搬过来的,大家别拿板砖砸我。)

还有另一个方便的技巧可以用来配置共享库路径。有时候希望告诉动态装入器在尝试任何 /etc/ld.so.conf 路径以前先尝试使用特定目录中的共享库。在运行的较旧的应用程序不能与当前安装的库版本一起工作的情况下,这会比较方便。

LD_LIBRARY_PATH

要指示动态装入器首先检查某个目录,请将 LD_LIBRARY_PATH 变量设置成您希望搜索的目录。多个路径之间用冒号分隔;例如:

# export LD_LIBRARY_PATH="/usr/lib/old:/home/burgess/gitlearn/test/lib"

导出 LD_LIBRARY_PATH 后,如有可能,所有从当前 shell 启动的可执行程序都将使用 /usr/lib/old 或 /opt/lib 中的库,如果仍不能满足一些共享库相关性要求,则转回到 /etc/ld.so.conf 中指定的库。

Linux下创建动态库与使用的更多相关文章

  1. linux下so动态库一些不为人知的秘密(转)

    linux 下有动态库和静态库,动态库以.so为扩展名,静态库以.a为扩展名.二者都使用广泛.本文主要讲动态库方面知识.基本上每一个linux 程序都至少会有一个动态库,查看某个程序使用了那些动态库, ...

  2. linux下so动态库一些不为人知的秘密

    linux 下有动态库和静态库,动态库以.so为扩展名,静态库以.a为扩展名.二者都使用广泛.本文主要讲动态库方面知识.    基本上每一个linux 程序都至少会有一个动态库,查看某个程序使用了那些 ...

  3. linux下so动态库一些不为人知的秘密(上)

    linux 下有动态库和静态库,动态库以.so为扩展名,静态库以.a为扩展名.二者都使用广泛.本文主要讲动态库方面知识.        基本上每一个linux 程序都至少会有一个动态库,查看某个程序使 ...

  4. linux下so动态库一些不为人知的秘密(中二)

    继续上一篇< linux下so动态库一些不为人知的秘密(中) >介绍so搜索路径,还有一个类似于-path,叫LD_RUN_PATH环境变量, 它也是把路径编译进可执行文件内,不同的是它只 ...

  5. linux下so动态库一些不为人知的秘密(中)

    上一篇(linux下so动态库一些不为人知的秘密(上))介绍了linux下so一些依赖问题,本篇将介绍linux的so路径搜索问题. 我们知道linux链接so有两种途径:显示和隐式.所谓显示就是程序 ...

  6. linux下c++动态库的生成及使用

    文章来源于:http://hi.baidu.com/ablenavy/item/b498901c6826bbf587ad4e33 我的程序是一个类,在网上找了半天,都是c的例子,c++的类封装成静态库 ...

  7. linux下生成动态库和链接动态库

    1.生成动态库 src/test.h #ifndef _TEST_H_HH #define _TEST_H_HH void print(); #endif src/test.cpp #include ...

  8. Linux 下创建静态库和动态库

    1.创建静态链接库 2.创建动态链接库

  9. Linux下设置动态库的方法

    库文件在连接(静态库和共享库)和运行(仅限于使用共享库的程序)时被使用,其搜索路径是在系统中进行设置的. 一般 Linux 系统把 /lib 和 /usr/lib 两个目录作为默认的库搜索路径,所以使 ...

随机推荐

  1. CS184.1X 计算机图形学导论(第五讲)

    一.观察:正交投影 1.特性:保持平行线在投影后仍然是平行的 2.一个长方体,对处在只有深度不同的位置上的同一物体来说,它的大小不会改变. 3.透视投影:平行线在远处会相交(例如铁轨) 4.glOrt ...

  2. Sass Maps的函数-map-remove($map,$key)、keywords($args)

    map-remove($map,$key) map-remove($map,$key) 函数是用来删除当前 $map 中的某一个 $key,从而得到一个新的 map.其返回的值还是一个 map.他并不 ...

  3. (HY000): Can't connect to MySQL server on '129.28.149.240' (113)

    环境 mysql5.7 ubuntu 一. 解决方法 1.首先确保mysql开启了远程授权:https://blog.csdn.net/cryhelyxx/article/details/401146 ...

  4. 洛谷4721 【模板】分治 FFT

    传送门 久违的多项式全家桶= =+ 分治NTT 用的就是cdq分治的思想 对于当前递归到的区间[l,r] 我们处理出[l,mid]对[mid+1,r]答案的贡献 然后分治递归求解就可以啦qwq 这个贡 ...

  5. 剑指Offer-51.构建乘积数组(C++/Java)

    题目: 给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1].不能 ...

  6. C#基础提升系列——C# 泛型

    C# 泛型(Generics) 泛型概述 泛型是C#编程语言的一部分,它与程序集中的IL(Intermediate Language,中间语言)代码紧密的集成.通过泛型,我们不必给不同的类型编写功能相 ...

  7. 【leetcode】878. Nth Magical Number

    题目如下: 解题思路:本题求的是第N个Magical Number,我们可以很轻松的知道这个数的取值范围 [min(A,B), N*max(A,B)].对于知道上下界求具体数字的题目,可以考虑用二分查 ...

  8. cocos2D-X 打包

    { //首先有java jdk,android sdk,android ndk //用android studio  import //匹配gradle 的版本 有些gradle可能下载不下来,不用慌 ...

  9. WIN10无法识别安卓设备,提示Windows 无法验证此设备所需的驱动程序的数字签名

    在设备管理器,显示ANDROID设备是感叹号, 不管更新驱动,还是下载什么手机助手自动安装驱动,均不可解. 从属性中查看提示的是“Windows 无法验证此设备所需的驱动程序的数字签名”, 解决办法: ...

  10. Spring学习总结(2)- AOP

    一,什么是AOP AOP(Aspect Oriented Programming)意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软件开发中 ...