posts - 403, comments - 310, trackbacks - 0, articles - 7
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

CSAPP - Linking - 动态链接库

Posted on 2007-08-07 23:10 ZelluX 阅读(657) 评论(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);

评论

# re: Linking - 动态链接库  回复  更多评论   

2007-08-08 00:55 by Lee.MaRS
我说看着这么眼熟,果然是CSAPP的说,hoho

# re: Linking - 动态链接库  回复  更多评论   

2007-08-08 14:55 by ZelluX
@Lee.MaRS
re
好书啊

只有注册用户登录后才能发表评论。


网站导航: