动态库的使用
编写动态库
(1)设计库代码
[bill@billstone make_lib]$ cat pr1.c
int p = 2;
void print(){
printf("This is the first dll src!\n");
}
[bill@billstone make_lib]$
(2)生成动态库
[bill@billstone make_lib]$ gcc -O -fpic -shared -o dl.so pr1.c
[bill@billstone make_lib]$ ls -l *.so
-rwxrwxr-x 1 bill bill 6592 4 月 15 15:19 dl.so
[bill@billstone make_lib]$
动态库的隐式调用
在编译调用库函数代码时指明动态库的位置及名字, 看下面实例
[bill@billstone make_lib]$ cat main.c
int main()
{
print();
return 0;
}
[bill@billstone make_lib]$ gcc -o tdl main.c ./dl.so
[bill@billstone make_lib]$ ./tdl
This is the first dll src!
[bill@billstone make_lib]$
当动态库的位置活名字发生改变时, 程序将无法正常运行; 而动态库取代静态库的好处之一则是通过更新动态库而随时升级库的内容.
动态库的显式调用
显式调用动态库需要四个函数的支持, 函数 dlopen 打开动态库, 函数 dlsym 获取动态库中对象基址, 函数 dlerror 获取显式动态库操作中的错误信息, 函数 doclose 关闭动态库.
[bill@billstone make_lib]$ cat main.c
#include <dlfcn.h>
int main()
{
void *pHandle;
void (*pFunc)(); // 指向函数的指针
int *p;
pHandle = dlopen("./d1.so", RTLD_NOW); // 打开动态库
if(!pHandle){
printf("Can't find d1.so \n");
exit(1);
}
pFunc = (void (*)())dlsym(pHandle, "print"); // 获取库函数 print 的地址
if(pFunc)
pFunc();
else
printf("Can't find function print\n");
p = (int *)dlsym(pHandle, "p"); // 获取库变量 p 的地址
if(p)
printf("p = %d\n", *p);
else
printf("Can't find int p\n");
dlclose(pHandle); // 关闭动态库
return 0;
}
编写动态库
(1)设计库代码
[bill@billstone make_lib]$ cat pr1.c
int p = 2;
void print(){
printf("This is the first dll src!\n");
}
[bill@billstone make_lib]$
(2)生成动态库
[bill@billstone make_lib]$ gcc -O -fpic -shared -o dl.so pr1.c
[bill@billstone make_lib]$ ls -l *.so
-rwxrwxr-x 1 bill bill 6592 4 月 15 15:19 dl.so
[bill@billstone make_lib]$
动态库的隐式调用
在编译调用库函数代码时指明动态库的位置及名字, 看下面实例
[bill@billstone make_lib]$ cat main.c
int main()
{
print();
return 0;
}
[bill@billstone make_lib]$ gcc -o tdl main.c ./dl.so
[bill@billstone make_lib]$ ./tdl
This is the first dll src!
[bill@billstone make_lib]$
当动态库的位置活名字发生改变时, 程序将无法正常运行; 而动态库取代静态库的好处之一则是通过更新动态库而随时升级库的内容.
动态库的显式调用
显式调用动态库需要四个函数的支持, 函数 dlopen 打开动态库, 函数 dlsym 获取动态库中对象基址, 函数 dlerror 获取显式动态库操作中的错误信息, 函数 doclose 关闭动态库.
[bill@billstone make_lib]$ cat main.c
#include <dlfcn.h>
int main()
{
void *pHandle;
void (*pFunc)(); // 指向函数的指针
int *p;
pHandle = dlopen("./d1.so", RTLD_NOW); // 打开动态库
if(!pHandle){
printf("Can't find d1.so \n");
exit(1);
}
pFunc = (void (*)())dlsym(pHandle, "print"); // 获取库函数 print 的地址
if(pFunc)
pFunc();
else
printf("Can't find function print\n");
p = (int *)dlsym(pHandle, "p"); // 获取库变量 p 的地址
if(p)
printf("p = %d\n", *p);
else
printf("Can't find int p\n");
dlclose(pHandle); // 关闭动态库
return 0;
}
[bill@billstone make_lib]$ gcc -o tds main.c –ld1 –L.
此时还不能立即./tds,因为在动态函数库使用时,会查找/usr/lib、/lib目录下的动态函数库,而此时我们生成的库不在里边。 这个时候有好几种方法可以让他成功运行: 最直接最简单的方法就是把libstr_out.so拉到/usr/lib或/lib中去。 还有一种方法 export LD_LIBRARY_PATH=$(pwd) 另外还可以在/etc/ld.so.conf文件里加入我们生成的库的目录,然后/sbin/ldconfig。 /etc/ld.so.conf是非常重要的一个目录,里面存放的是链接器和加载器搜索共享库时要检查的目录,默认是从/usr/lib /lib中读取的,所以想要顺利运行,我们也可以把我们库的目录加入到这个文件中并执行/sbin/ldconfig 。另外还有个文件需要了解/etc/ld.so.cache,里面保存了常用的动态函数库,且会先把他们加载到内存中,因为内存的访问速度远远大于硬盘的访问速度,这样可以提高软件加载动态函数库的速度了。