一 静态库的生成步骤:
1 写源程序,以PrintS.c为例,保存退出。
2 编译源程序,得到目标文件(.o文件)。
gcc -c 源文件名
例:PrintS.c
#include <stdio.h>
void printS(){
printf( " *\n");
printf( "***\n");
printf( " *\n");
}
通过以下命令生成.o目标文件PrintS.o
# gcc -c PrintS.c
3 打包生成静态库文件
ar -r lib名字.a xx.o (.o文件可以多个)
库文件名字 命名规范:以lib开头,以 .a结束
通过以下命令生成静态库文件 libPrintS.a
# ar -r libPrintS.a PrintS.o
4 静态库的调用步骤:
1 写调用的源程序 test.c ,保存退出
2 编译代码,生成 .o文件。
3 连接test.o 和 静态库,连接方式有三种:
a) gcc test.o lib名字.a (直接连)
b) 先配置环境变量LIBRARY_PATH,把静态库文件所在的路径配置进去,然后:
gcc test.o -l库名字 (库名字去掉lib和.a)
c) gcc test.o -l库名字 -L库路径
abc里选一个,比如用a中的直接链接,这时,当前目录应该有
PrintS.c PrintS.o test.c test.o libPrintS.a
接着,在test.c里调用printS()函数,输入命令
# gcc test.o libPrintE.a
#./a.out
root@ley: ~/myStudy/PrintTest$ ./a.out
*
***
*
二 共享库的生成步骤:
1 编写源程序,以PrintE.c为例,保存退出
#include <stdio.h>
void printE(){
printf(" *\n");
printf("* *\n");
printf(" *\n");
}
2 编译源程序,生成 .o文件PrintE.o
gcc -c -fpic PrintE.c (不写-fpic也行)
root@ley: ~/myStudy/PrintTest$ gcc -c -fpic PrintS.c
3 生成共享库文件(.so)
gcc -shared add.o -olib名字.so
当文件较多时,头/源文件需要规范
root@ley: ~/myStudy/PrintTest$ gcc -shared PrintS.o -olibPrintS.so
4 共享库的使用步骤
共享库的使用步骤 与 静态库基本相同。
注:共享库的连接方式和静态库一样,但在运行时需要额外配置环境变量 LD_LIBRARY_PATH,否则就找不到库文件。
export LD_LIBRARY_PATH=. 表示引用当前目录为查找库文件的路径
ldd 命令可以查看共享库的调用关系,如键入 ldd 库文件名,则会显示库依赖关系, libc.so.6 就是c的共享库
root@ley:~/myStudy/PrintTest$ ldd libPrintS.so
linux-vdso.so.1 => (0x00007ffc1e4f9000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9c0aa26000)
/lib64/ld-linux-x86-64.so.2 (0x00007f9c0aff2000)
root@ley:~/myStudy/PrintTest$
三 程序中使用动态库/共享库
就像打开一个文件一样的使用,类似fopen fclose那套文件操作
步骤:
1 打开一个共享库文件。dlopen()
2 在打开的共享库文件中获取一个函数。dlsym()
3 执行函数 func_in_ld_lib()
4 关闭共享库文件。dlclose()
dlerror() 处理错误信息
以上调用动态库时,test.c中就是按照这个顺序,调用自定义函数 printE()
test.c:
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
int main(){
void* handle;
void (*print)();
char* error;
handle = dlopen("libPrintE.so",RTLD_NOW);
if(!handle){
fprintf(stderr,"%s\n",dlerror());
exit(EXIT_FAILURE);
}
dlerror();
print = (void (*)())dlsym(handle,"printE");
error = dlerror();
if(error != NULL)
{
fprintf(stderr,"%s\n",error);
exit(EXIT_FAILURE);
}
print();//调用printE()
dlclose(handle);
exit(EXIT_SUCCESS);
}
4 共享库的使用步骤
共享库的使用步骤 与 静态库基本相同。
注:共享库的连接方式和静态库一样,但在运行时需要额外配置环境变量 LD_LIBRARY_PATH,否则就找不到库文件。
export LD_LIBRARY_PATH=.
再说下函数dlopen() 它有两个参数,第一个参数是文件名,第二个参数必须是:RTLD_LAZY 或 RTLD_NOW,
区别:
RTLD_LAZY - 延迟加载,open时不真正加载,到使用时再加载。
RTLD_NOW - 现在加载,open的同时完成加载
而 dlerror()在调用 dlopen/dlsym/dlclose之后立刻调用,效果:如果上面的函数出现错误,返回错误信息,如果没有错误,返回NULL。