Posted on 2007-08-07 23:10
ZelluX 阅读(669)
评论(2) 编辑 收藏 所属分类:
C/C++ 、
System
1. 静态库(static library)的主要缺陷:
1) 静态库通常需要维护和定期更新,而这些库的使用者就得注意这些变化,并且在库修改后重新将自己的程序和库链接起来
2) 以printf和scanf这两个函数为例,它们的代码在每个运行的进程里都保留了一份,在一个典型的操作系统上运行着50-100个进程,这无疑是对系统资源的严重浪费。(内存的一个有趣的特性是,它永远是一个短缺的资源,无关一个系统里有多大的内存)
2. 共享库(shared library)弥补了静态库的这些缺陷。所谓共享库,就是指在运行时可以被读入到任意的内存地址,并与程序链接的模块。这个过程也被称为动态链接(dynamic linking),由动态链接器(dynamic linker)完成。
Unix系统中共享对象通常后缀为.so,微软的操作系统中大量使用了共享库,通常被称为DLL(dynamic link libraries)
3. 共享库的“共享”表现在两个方面:
1) 在任何一个给定的文件系统中,对于某个特定的库,只有一个.so文件
2) 共享库单独的一份.text域可以由多个不同的运行进程共享。
4. 编译一个共享库:gcc -shared -fPIC -o libvector.so addvec.c multvec.c
-fPIC开关让编译器产生位置独立的代码(PIC, position independent code)
-shared开关使得编译器产生共享对象的文件
5. 动态链接的几个应用:
1) 软件的分布式开发
2) 开发高效的Web服务器
早期的Web服务器通过fork和execve调用子进程来产生动态的内容,被称为CGI,而现代的Web服务器则通过基于动态链接库的一种高效的方式。
主要的方法是把生成动态内容的函数打包到一个共享库中,当服务器端接收到一个请求后,服务器动态地读入并且链接到相应的函数,并直接调用这个函数,而
fork和execve则是在子进程的环境中运行的。函数调用后继续存在,以后的类似请求都只需要一个简单的调用就可以了。另外,方法也可以在不停止服务
器的情况下更新,也可以加入新的函数。
6. Unix系统中读入并链接共享库的方法
#include <dlfcn.h>
void *dlopen(const char *filename, int flag);
// returns: ptr to handle if OK, NULL on error
需要通过-rdynamic编译,具体见CSAPP P569
获得已经打开的库的句柄(handle)
#include <dlfcn.h>
void #dlsym(void *handle, char *symbol);
// returns: ptr to symbol if OK, NULL on error
关闭共享库
#include <dlfcn.h>
int dlclose(void *handle);
// returns: 0 if OK, -1 on error
获得错误信息
#include <dlfcn.h>
const char *dlerror(void);