官方说明
Linking Libraries
链接库的行为是代码依赖管理的一种形式。
当任何应用程序运行时,其可执行代码被加载到内存中。
此外,它所依赖的任何代码库也会加载到内存中。
有两种类型的链接:静态和动态。
Dynamic Linking
动态链接最常用于OS X和iOS。
当动态库链接时,库中的代码都不会直接包含在链接的目标中。
相反,在符号得到解决之前,库会在运行时加载到内存中。
由于代码没有静态链接到可执行二进制文件中,因此在运行时加载有一些好处。
主要的是,这些库可以使用新功能或错误修复进行更新,而无需重新编译和重新链接可执行文件。
此外,在运行时加载意味着各个代码库可以拥有自己的初始化程序,并在从内存中卸载之前清理自己的任务。
For more information on overview and design, see Apple's Dynamic Library Programming Topics.
Libraries
动态库是一种Mach-O binary1,在应用程序的启动或运行时加载。
由于动态库中的可执行代码并未静态链接到目标可执行文件中,因此在需要重复使用相同代码时,这会减少内存消耗。
由于动态库在运行时被加载,所以库负责告诉链接器需要哪些附加代码。
这消除了管理你使用的所有代码需要操作的负担。
Frameworks
Dynamic frameworks
和 dynamic libraries
类似。
两者都是动态链接库,除了dynamic framework
是嵌入在一个bundle
中的动态库。
这允许对动态库进行版本控制以及对libraries代码使用的其他资源进行排序。
Example
Building
举例:
bar.h
#ifndef __foo__bar__
#define __foo__bar__
#include <stdio.h>
int fizz();
#endif
bar.c
#include "bar.h"
#include <CoreFoundation/CoreFoundation.h>
int fizz() {
CFShow(CFSTR("buzz"));
return 0;
}
从文件bar.h和bar.c开始。
头文件定义了函数fizz(),它返回一个整数值。
实现文件导入CoreFoundation框架并实现函数fizz在返回0之前打印字符串“buzz”
Compiling:
$ clang -c bar.c -o bar.o
这将创建名为“bar”的对象file2,类型为MH_OBJECT的Mach-O二进制文件。
One of these will be generated for each of the files compiled in the library.
Creating Library:
$ libtool -dynamic bar.o -o libfoo_dynamic.dylib -framework CoreFoundation -lSystem
这会创建dylib(动态库)并链接到libSystem和CoreFoundation.framework。 dylib是一个类型为MH_DYLIB的Mach-O二进制文件。这将在启动时由dyld动态加载,作为另一个二进制文件的依赖关系。
Linking
main.c
#include "bar.h"
int main() {
return fizz();
}
在这个例子中,为动态库导入“bar.h”头,并直接调用fizz()。
Compiling
$ clang -c main.c -o main.o
This will generate the object file for main.
Linking:
$ ld main.o -lSystem -L. -lfoo_dynamic -o test_dynamic
这将从主目标文件生成一个二进制可执行文件,并且也会传递
- -lSystem for dyld_stub_binder
- -lfoo_dynamic for linking against libfoo_dynamic.dylib
Running:
Symbols:
$ nm test_dynamic
0000000000001000 A __mh_execute_header
U _fizz
0000000000001fa0 T _main
U dyld_stub_binder
References:
$ otool -L test_dynamic
test_dynamic:
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)
libfoo_dynamic.dylib (compatibility version 0.0.0, current version 0.0.0)
生成的二进制文件仅链接到libSystem和创建的dylib。
库foo_dynamic负责链接它所需的任何附加库。
这是在发布时动态解决的。
在这种情况下,libfoo_dynamic.dylib的搜索路径将与主要可执行文件的搜索位置相同。
动态库和框架在启动时由动态链接器加载。
它们具有相关的搜索路径,以帮助链接程序找到它们在文件系统上的位置并加载它们。
Static Linking
与动态链接不同,链接静态库包含库中的目标文件代码到目标的二进制文件中。
这会导致更占空间,启动时间更慢。
由于库的代码直接添加到链接目标的二进制文件,这意味着要更新库中的任何代码,链接目标也必须重新构建。
在iOS 8之前,静态链接库是事实上的出货方式,并在应用程序中包含任何第三方代码。
略
参考出处
https://pewpewthespells.com/blog/static_and_dynamic_libraries.html