# 正文
前一篇说找到了这个资料:
https://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html;
它的首页是https://tldp.org/HOWTO/Program-Library-HOWTO/index.html。
原文很好懂,所以我这里算是写一下自己学到的东西,不是翻译,也不按顺序,先整理一下静态库、共享库以及动态库的最简单例子,因为觉得有人会喜欢看一下这个然后自己研究。
静态库示例
编一个静态库的代码libhello.c:
编译静态库libhello-static.a:
- gcc -Wall -g -c -o libhello-static.o libhello.c
- ar rcs libhello-static.a libhello-static.o
写一个使用hello()函数的main.c:
编译main.c,得到可执行程序main,命令:
- gcc -Wall -g -c main.c -o main.o
- gcc -g -o main main.o -L ./ -lhello-static
共享库示例
库的代码还是用libhello.c,不过这次多打印一个换行:
编译共享库libhello.so,命令:
- gcc -fPIC -Wall -g -c libhello.c
- gcc -g -shared -Wl,-soname,libhello.so.0 -o libhello.so.0.0 libhello.o -lc
原文这里提到过因为libhello依赖C library,所以使用了-lc选项;实际上不使用好像也没问题,大概因为原文是2003年的文档,后来新版的gcc不需要这个了,这不是重点,验证过程放到endnote1,继续。
现在把libhello.so.0.0挪到/usr/local/lib/,并使用ldconfig创建共享库缓存:
可以看到ldconfig创建了一个名为/usr/local/lib/libhello.so.0的符号连接。
现在我们手动创建一个名为 libhello.so的软连接:ln -sf libhello.so.0 libhello.so
然后使用共享库编译可执行程程序main:
- gcc -Wall -g -c main.c -o main.o
- gcc -g -o main main.o -L /usr/local/lib -lhello
执行一下试试:
PS: 这里编译得到的可执行程序main的过程中就没有像上一篇那样的现象了(endnote2)
动态库示例
编写一个使用动态库的main.c:
代码贴到endnote3了。
部署/root/d/libhello.so.0.0,就是把上一步得到的共享库拷贝过来了事:
编译可执行程序main:
- gcc -Wall -g -c main.c
- gcc -g -o main main.o -ldl
注意,这里不需要告诉gcc去哪里查找libhello.so.0.0,因为只有执行的时候才加载libhello.so.0.0,但是需要使用gcc的-ldl选项以包含加载动态库的那些库。
文章好像有点简单,好在原文清晰又详细,贴一下连接,文章算欧了:
https://tldp.org/HOWTO/Program-Library-HOWTO/more-examples.html
# ENDNOTES
endnote1
不使用-lc选项,编一下libhello.so.0.0
使用ldconfig创建动态库缓存:
编译可执行程序main,ldd查看一下它依赖的共享库:
执行一下,发现也符合期望:
endnote2
就是这个现象:
endnote3
#include <dlfcn.h>
#include <stdlib.h>
#include <stdio.h>
typedef void (*ddl_demo_func)(void);
int main(void){
const char *error;
void *module;
ddl_demo_func demo_func; //变量demo_func是一个指向函数的指针
module = dlopen("/root/d/libhello.so.0.0", RTLD_LAZY);
if(!module){
fprintf(stderr, "could not open libhello.so.0.0: %s\n", dlerror());
exit(1);
}
dlerror();
demo_func = dlsym(module, "hello");
if ((error = dlerror())){
fprintf(stderr, "could not find hello: %s\n", error);
exit(1);
}
(*demo_func)(); //调用函数hello()
dlclose(module);
return 0;
}