Linker
In computer science, a linker or link editor is a computer program that takes one or more object files generated by a compiler and combines them into a single executable program.
Static Linking
静态链接是在编译期(compile time)进行的链接,
好处:
- 没有依赖问题,一旦可以静态链接,生成的object file,或者可执行程序,不存在依赖问题
- 更容易分发,静态库可以直接copy到最终的exe中,从而可以只有一个exe,便于软件分发
- 性能提升
坏处:
- 分发的文件会比较大(静态链接库链接到exe后,相比动态链接,exe会更大,但如果算上链接库本身,动态链接 和静态链接尺寸会相当,但在*nix环境中,通常动态库是共享的,执行文件分发时不包含依赖的动态库,因而会 比静态链接尺寸小;Windows则在动态库共享方面存在DLL Hell问题-版本不匹配等,所以dll会与可执行文件 打包在一起)
例如,有a.h, a.c, main.c三个文件,其中main.c引用a.h中的函数,
- gcc -c a.c // 生成a.o object file
- ar rcs libmyclass.a a.o // 生成 libmyclass.a 静态链接库
- gcc main.c libmyclass.a // 生成可执行文件 a.out
- 3等价于 gcc main.c a.o
Dynamic Linking
摘自wikipedia, In computing, a dynamic linker is the part of an operating system (OS) that loads (copies from persistent storage to RAM) and links (fills jump tables and relocates pointers) the shared libraries needed by an executable at run time, that is, when it is executed.
动态链接是操作系统相关的,不同操作系统的动态链接机制不同。
好处(相比静态链接):
- 更方便创建
- 更方便更新
- 可以允许调用程序在运行时加载和卸载
- 可以达到与静态链接库相同的语义(或者近似相同)
坏处:
- 性能损失(一些链接工作需要在运行时完成,静态链接库在编译时完成)
- 比静态链接库大(包含符号表)
- 动态链接库的符号需要在符号表中查找和确认(resolve)
例如,有a.h, a.c, main.c三个文件,其中main.c引用a.h中的函数,
- gcc -fpic -c a.c //生产a.o, pic意思是Position Independent Code
- gcc -shared -olibmyclass.so a.o //生产了libmyclass.so
- gcc -L/PATH_TO_THE_SO/ -lmyclass main.c // /PATH_TO_THE_SO/说明so的位置(如果不在标准 的位置/usr/lib, /usr/local/lib)
当然如果so在标准位置,则只需要 gcc -lmyclass main.c即可。
另外也可以使用dlopen/dlsym(Unix like OS)来加载和使用动态链接库。
Object Library
OOP成为主流的编程方法后,支持OO的library也成为业内一个重要的研究对象。 OOP最为重要的继承、动态绑定等要求相应的库有更多的信息。
比较有名的方案如微软的COM/DCOM等。
如果使用dlopen/dysym/dlclose来动态加载动态库时,需要注意name mangling问题。 简单地说dlopen等是为C语言设计的,symbol和函数名相同,而C++等OO语言,由于支持多态(一个名称,不同参数), 此时一个symbol不对应一个函数名,于是就有了name mangling, 会将函数名map为如foo@3$4这样只有编译器知道的 名称,而且mangling规则C++并没有规定,不同编译器的规则并不相同。
解决方案参考http://tldp.org/HOWTO/C++-dlopen/thesolution.html, 简单列举如下:
- 使用extern来将C++的方法标记为C的方法,避免name mangling
- 使用类的工厂函数(create/destroy)来创建和销毁类
Remote Library
当library不在本地时,对于远程的调用,即所谓的RPC,通常用于C/S结构的系统,也会有较长的 调用时间。