工程中的每个C语言源文件被编译后产生目标文件,这些目标文件如何生成最终的可执行程序呢?
链接器:
静态链接:
静态链接就是将库文件或者目标文件直接加入到可执行文件当中。
Linux下静态库的创建和使用:
静态库示例程序:20-1.c
1 #include <stdio.h> 2 3 extern char* name(); 4 extern int add(int a, int b); 5 6 int main() 7 { 8 printf("Name: %s ", name()); 9 printf("Result: %d ", add(2, 3)); 10 11 return 0; 12 }
slib.c
1 char* name() 2 { 3 return "Static Lib"; 4 } 5 6 7 int add(int a, int b) 8 { 9 return a + b; 10 }
将slib.c制作成静态库:
先将slib.c编译成slib.o,然后用ar命令进行打包,生成slib.a。ar命令是打包命令,会将后面列出的所有文件打包进slib.a中,slib.a就是一个档案文件,这个档案文件就是静态库。
编译源程序,并去链接我们刚才生成的静态库,如下:
删掉slib.a后,程序依然可以执行,这说明,惊天库完全被链接进了最终的可执行文件中,这就是静态链接。最终的可执行程序的运行,与静态库和其它目标文件已经无关了。
动态链接:
动态链接是在程序运行的时候再到动态库中查找内容。
动态库的内容是不会进入最终的可执行程序当中的。
stub1和stub2就是这两个so动态库文件中暴露给编译器的接口,告诉编译器,我们这两个动态库能提供的内容就是stub1和stub2的内容。编译链接出来的程序使用stub1和stub2中的内容,其它的内容是看不到的。
Linux下动态库的创建和使用:
示例程序:
20-1.c
1 #include <stdio.h> 2 #include <dlfcn.h> 3 4 int main() 5 { 6 void* pdlib = dlopen("./dlib.so", RTLD_LAZY); 7 8 char* (*pname)(); 9 int (*padd)(int, int); 10 11 if( pdlib != NULL ) 12 { 13 pname = dlsym(pdlib, "name"); 14 padd = dlsym(pdlib, "add"); 15 16 if( (pname != NULL) && (padd != NULL) ) 17 { 18 printf("Name: %s ", pname()); 19 printf("Result: %d ", padd(2, 3)); 20 } 21 22 dlclose(pdlib); 23 } 24 else 25 { 26 printf("Cannot open lib ... "); 27 } 28 29 return 0; 30 }
dlib.c
1 char* name() 2 { 3 return "Dynamic Lib"; 4 } 5 6 7 int add(int a, int b) 8 { 9 return a + b; 10 }
编译执行结果如下:
gcc -shared dlib.c -o dlib.so命令生成动态库。
动态链接生成可执行文件时,一定要加上-ldl选项。
删掉dlib.so,再次执行可执行程序:
这说明,在执行时test.out是依赖dlib.so的。
小结: