本文重点参考了资源http://www.cppblog.com/fwxjj/archive/2009/06/02/86600.html。
比较推荐的关于Linux动态库的文章
http://www.ibm.com/developerworks/cn/linux/l-dynamic-libraries/ (中文版)
http://www.ibm.com/developerworks/linux/library/l-dynamic-libraries/index.html (英文版)
在Linux中可以调用动态链接库,其使用方法如下:
1. 先生成一个动态库libtest.so
/* test.c */
#include <stdio.h>
void my_test(int no)
{
printf("*****************\n");
printf("This is my test, the number is %d.\n", no);
printf("*****************\n");
}
编译库:
gcc -fPIC -shared -o libtest.so test.c
这样就可以生成libtest.so动态库。
在这个库里,定义个函数my_test,下面将在程序中加载libtest.so,然后调用my_test。
2. 加载动态库libtest.so
根据调用方式的不同,对动态库的调用可分为动态链接(Dynamic Linking)和动态加载(Dynamic Loading)方式。
2.1 动态链接
动态链接在编译期间指定动态库的位置及名称。例如:
/* main.c */
int main()
{
my_test(10);
return 0;
}
编译命令为:
gcc -o main main.c -L ./ -ltest
-L指定动态链接库的路径,-ltest指定了库名(libtest.so )。
但是这时候执行可执行程序main会产生如下错误:
error while loading shared libraries: libtest.so: cannot open shared object file: No such file or directory
这是由于程序运行时没有找到动态链接库。程序编译时链接动态库和运行时使用动态库的概念是不同的。
Linux下可用通过设置环境变量LD_LIBRARY_PATH来指定链接库的搜索路径,例如在csh下可以这样设置该变量:
setenv LD_LIBRARY_PATH $path_of_your_library
这样,运行main,将会看到调用my_test的结果:
*****************
This is my test, the number is 10
*****************
2.2 动态加载
动态加载在程序运行期通过特定的函数来加载动态库。例如:
/* main.c */
#include <stdio.h>
#include <dlfcn.h> // This header is required to load dynamic lib
#include <assert.h>
int main()
{
void *handler = dlopen("./libtest.so", RTLD_NOW);
assert(handler != NULL);
void(*test)(int) = dlsym(handler, "my_test");
assert(test != NULL);
(*test)(10);
dlclose(handler);
return 0;
}
在这个程序中,dlopen函数用来打开一个动态库,其返回一个void *的指针,如果失败,返回NULL。
dlsym返回一个动态库中的一个函数指针,如果失败,返回NULL。
dlclose关闭指向动态库的指针。
编译的时候需要加上 -ldl:
gcc -o main main.c -ldl(编译时要使用共享库dl 其中有dlopen dlsynm dlerror dlclose 函数)
运行main,将会看到调用my_test的结果:
*****************
This is my test, the number is 10
*****************