temp
来源:互联网 发布:美国全球的盟友网络 编辑:程序博客网 时间:2024/05/21 10:57
目标文件就是源代码编译后但未进行链接的那些中间文件(Windows的.obj和Linux下的.o),它跟可执行文件的内容与结构很相似,所以一般跟可执行文件格式一起采用一种格式存储。
#include <stdio.h>
void foo()
{
printf("%s","I am from mylib!\n");
}
用
cl /c /MLd mylib.c
( ML 要是大写的,否则不认。)
命令编译,注意 /MLd 选项是指定 libcd.lib 为默认标准库。 lib.exe 是 VC 自带的用于将目标文件打包成程序库的命令,所以我们可以用
lib /OUT:my.lib mylib.obj
将 mylib.obj 打包成库,输出的库文件名是 my.lib 。接下来把 main.c 改成 :
/* main.c */
void foo();
int main()
{
foo();
return 0;
}
用
cl /c main.c
编译,然后用
link main.obj my.lib
一开始 E 、 U 、 D 都是空集,链接器首先扫描到 main.obj ,把它加入 E 集合,同时把未解析的 foo 加入 U ,把 main 加入 D ,而且因为 main.obj 的默认标准库是 libc.lib ,所以它被加入到当前输入文件列表的末尾。
接着扫描 my.lib ,因为这是个库,所以会拿当前 U 中的所有符号 ( 当然现在就一个 foo) 与 my.lib 中的所有目标模块 ( 当然也只有一个 mylib.obj) 依次匹配,看是否有模块定义了 U 中的符号。
结果 mylib.obj 确实定义了 foo ,于是它被加入到 E , foo 从 U 转移到 D , mylib.obj 引用的 printf 加入到 U ,同样地, mylib.obj 指定的默认标准库是 libcd.lib ,它也被加到当前输入文件列表的末尾 ( 在 libc.lib 的后面 ) 。
不断地在 my.lib 库的各模块上进行迭代以匹配 U 中的符号,直到 U 、 D 都不再变化。很明显,现在就已经到达了这么一个不动点,所以接着扫描下一个输入文件,就是 libc.lib 。
链接器发现 libc.lib 里的 printf.obj 里定义有 printf ,于是 printf 从 U 移到 D ,而 printf.obj 被加入到 E ,它定义的所有符号加入到 D ,它里头的未解析符号加入到 U 。
链接器还会把每个程序都要用到的一些初始化操作所在的目标模块 ( 比如 crt0.obj 等 ) 及它们所引用的模块 ( 比如 malloc.obj 、 free.obj 等 ) 自动加入到 E 中,并更新 U 和 D 以反应这个变化。
事实上,标准库各目标模块里的未解析符号都可以在库内其它模块中找到定义,因此当链接器处理完 libc.lib 时, U 一定是空的。最后处理 libcd.lib ,因为此时 U 已经为空,
所以链接器会抛弃它里面的所有目标模块从而结束扫描,然后合并 E 中的目标模块并输出可执行文件。
- temp
- temp
- temp
- temp
- temp
- temp
- temp
- temp
- TEMP
- temp
- temp
- Temp
- temp
- Temp
- TEMP
- Temp
- temp
- temp
- 20170602memo
- Android Studio出现Failed to open zip file问题的解决方法
- Kotlin学习笔记——类和对象
- Android
- java中yield()方法如何使用
- temp
- 正则表达式回溯
- 模拟上帝之手的对抗博弈——GAN背后的数学原理
- 推荐几个精致的web UI框架
- Android Audio回声消除学习笔记
- Docker使用pure-ftp的方法及配置
- 在Android源码中如何吧so库打包编译进入apk, 集成第三方库(jar和so库)
- 简述Java的访问修饰符类型?分别有什么功能?
- Oracle TFA日志收集工具简介