工程中的每个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\n", name());
 9     printf("Result: %d\n", 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\n", pname());
19             printf("Result: %d\n", padd(2, 3));
20         }
21 
22         dlclose(pdlib);
23     }
24     else
25     {
26         printf("Cannot open lib ...\n");
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的。

小结:

 

posted on 2018-08-26 10:30  周伯通789  阅读(188)  评论(0编辑  收藏  举报