Linux 下c的动态链接库的生成
动态链接库不是linux独有的特性,在windows下面也存在这样的特性。一般来说,windows下面的动态连接库是以*.dll作为结尾的,而linux下面的动态连接库是以*.so结尾的。和静态链接库相比,动态连接库可以共享内存资源,这样可以减少内存消耗。另外,动态连接是需要经过操作系统加载器的帮助才能被普通执行文件发现的,所以动态连接库可以减少链接的次数。有了这个特点,我们就不难发现为什么很多软件的补丁其实都是以动态库发布的。
动态链接库不是linux独有的特性,在windows下面也存在这样的特性。一般来说,windows下面的动态连接库是以*.dll作为结尾的,而linux下面的动态连接库是以*.so结尾的。和静态链接库相比,动态连接库可以共享内存资源,这样可以减少内存消耗。另外,动态连接是需要经过操作系统加载器的帮助才能被普通执行文件发现的,所以动态连接库可以减少链接的次数。有了这个特点,我们就不难发现为什么很多软件的补丁其实都是以动态库发布的。
最近Google了一阵子,总结了如何制作自己的动态链接库的资料,菜鸟级别,可能有错,望指出
主要的步骤是:1 编写自己的Linux库的源文件(*.h , *.c)-->> 2 编译生成动态库-->>使用动态库
1: 编写自己的Linux库的源文件(*.h , *.c)
先编写头文件
#ifndef _MYP_
#define _MYP_
int MyP( int ) ;
#endif
Analysis: 其中_MYP_在这里目的是防止头文件的重复包含和编译。这个标识可以*命名,每个头
文件的这个标识都应该是唯一的。表示的命名空间一个是头文件名全大写,前面加下划线,并把文件的"."
也变成下划线,如:stdio.h
#ifndef _STDIO_H
#define _STDIO_H
再编写有文件对应的实现功能的源文件()
#include"MyP.h"
int MyP(int i )
{
printf("i=%d\n",i);
return i ;
}
2:编译生成动态库
gcc MyP.c -fPIC -shared -o libmyp.so
Analysis:
经过上面的command会生成动态库libmyp.so ,为了不需要动态加载动态库,在命令是需要加上以lib
开头以.so为后缀。
-fPIC表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的,所以动态载入时是
通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。
–shared:指明编译成动态库。
3: use dynamic library
首先编译时使用动态库
注:使用的动态库
#include"MyP.h"
int main()
{
MyP(3);
return 0;
}
对应的文件名test.c
编译command:
gcc test.c -L . -l myp -o test
-L :动态库锁在的目录
-l:动态库的名称,该名称是处在头lib和后缀.so中的名称,如上动态库libtest.so的l参数为-ltest
ldd test
ldd 测试可执行文件所使用的动态库
注意:上面的办法应该是对的,只是本人测试,发现找不到myp库,只能把编译后的libmyp.so文件copy到/lib/目录下才通过
除此之外还有一种方法,比如上面可以用下面的命令:
gcc test.c -o test ./libmyp.so
这样就不会出错了,由于是动态库,所以如果删除libmyp.so后,再运行./test程序,程序就会出错,会提示找不到相应的库文件。
gcc test.c -o test ./libmyp.so
这样就不会出错了,由于是动态库,所以如果删除libmyp.so后,再运行./test程序,程序就会出错,会提示找不到相应的库文件。
error while loading shared libraries的解決方法
在linux下运行程序时,发现了error while loading sharedlibraries这种错误,一时间不知道解决办法,在网上搜索,终于解决了:
./tests: error while loading shared libraries: xxx.so.0:cannotopen shared object file: No such file or directory
出现这类错误表示,系统不知道xxx.so放在哪个目录下,这时候就要在/etc/ld.so.conf中加入xxx.so所在的目录。
一般而言,有很多的so会存放在/usr/local/lib这个目录底下,去这个目录底下找,果然发现自己所需要的.so文件。
所以,在/etc/ld.so.conf中加入/usr/local/lib这一行,保存之后,再运行:/sbin/ldconfig–v更新一下配置即可。