博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
深入探究VC —— 链接器link.exe(4)【转】http://blog.csdn.net/wangningyu/article/details/4849452...
阅读量:5280 次
发布时间:2019-06-14

本文共 2812 字,大约阅读时间需要 9 分钟。

在程序编译完成后,生成的文件是以.obj为扩展名的对象文件,link.exe是将这些对象文件与库链接起来以创建可执行文件或动态链接库文件的工具。

 

link.exe的输入文件包括obj文件、lib文件、exp文件、def文件、res文件、txt文件、ilk文件等等,而输出的文件一般是exe文件、dll文件、sys文件等可执行程序文件。

 

1、命令行参数

link.exe运行参数如下:

LINK [options] files

参数包括选项和文件名,选项和文件名可按任意顺序指定。link会首先处理选项,然后是文件。各参数间必须使用一个或多个空格或制表符来分隔。

 

2、输入文件

参数中的files是指链接器的输入文件。用户可以使用文件名指定绝对路径或相对路径,可在文件名中使用通配符。如果用户指定的文件名没有扩展名,则默认假设扩展名为obj。link.exe对文件格式的判断不是根据文件扩展名,而是判断文件的内容。

比如之前代码中:

 

[cpp] 
  1. // File   Name: Hello.c     
  2. // Description: First Win32 Application     
  3. // by Koma 2009-11-18 22:05     
  4.     
  5. #include <windows.h>     
  6. #pragma comment(lib,"user32.lib")     
  7.     
  8. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pszCmdLine, int cmdShow)     
  9. {     
  10.     MessageBox(NULL,"Hello World !","Test",MB_OK);     
  11.     return 0;     
  12. }  

 

 

Hello.c完成编译后会生成Hello.obj文件,然后将Hello.obj与系统库文件链接起来,最终生成可执行文件。命令行参数为:

link Hello.obj /subsystem:windows

 

注意,在之前代码中有这样一行代码:

 

[cpp] 
  1. #pragma comment(lib,"user32.lib")    

 

如果在输入文件中指明了user32.lib,那么这一行是没有必要的。但是如果将参数里这一段链接user32.lib去掉,而代码文件中又不包括 上面这一行,则编译器会报错。

 

如果编译器报告错误“LNK2019:无法解析的外部符号......”,那么通常是由于没有将链接这些符号所需要的输入库文件加入到输入文件参数中,比如调用MessageBox API就必须在链接时输入user32.lib。

 

3、链接器选项

选项前需加“选项说明符”(一个短划线‘-’或一个正斜杠‘/’),然后是该选项的名称。如果选项带参数,参数在冒号(:)后指定选项的参数。如果参数是数值,可以使用十进制、或C语言表示法。与编译器cl.exe不同,链接器的选项名及其关键字或文件名参数不区分大小写,但用作参数的标识符区分大小字书。

 

选项中很多涉及Windows可执行文件的格式问题,比如节、导入表、导出表、基地址等,以及Windows可执行文件中EXE文件、DLL文件的区别与作用、可执行文件的加载以及API函数动态链接过程。(Windows可执行文件编译与链接的内部原理,请自行查阅相关资料吧!)

 

选项

用途

指定响应文件

指定每一节的对齐方式

指定 DLL 不能绑定

指定清单查找的行为。

将  添加到托管映像中。

创建指向托管资源的链接。

指定应将 Microsoft 中间语言 (MSIL) 模块导入到程序集中

将托管资源文件嵌入到程序集

为程序设置基址

设置 CLR 映像的类型(IJW 映像、纯映像或安全映像)。

保留通过 P/Invoke 机制调用的函数的上一个错误代码。

指定要应用于 CLR 程序入口点的线程属性。

/CLRUNMANAGEDCODECHECK 指定链接器是否将 SuppressUnmanagedCodeSecurity 属性应用于链接器生成的、从托管代码调用到本机 DLL 中的 PInvoke 存根 (stub)。

创建调试信息

将模块定义 (.def) 文件传递到链接器

在解析外部引用时搜索指定的库

控制 DLL 的延迟加载

导致延迟加载指定的 DLL

对程序集进行部分签名。

生成 DLL

创建 Windows NT 核心模式驱动程序

使用 Windows Vista 的地址空间布局随机化 (ASLR) 功能,指定是否生成可在加载时随机重新设定基址的可执行文件映像。

设置起始地址

向 Microsoft 报告内部链接器错误。

导出函数

创建只能在其首选基址加载的程序

强制完成链接,即使符号无法解析或已定义多次

创建可热修补的映像。

设置堆的大小(以字节为单位)

指定 .idl 文件和其他 MIDL 输出文件的名称

防止将属性信息处理到 .idl 文件中

重写默认的导入库名

强制符号引用

控制增量链接

指定用来为程序集签名的密钥容器。

指定用来为程序集签名的密钥或密钥对。

通知编译器应用程序支持大于 2 GB 的地址

允许用户重写环境库路径

指定链接时代码生成

指定目标平台

创建并行清单文件。

在清单文件中指定 <dependentAssembly> 节。

更改清单文件的默认名称。

指定是否将用户帐户控制 (UAC) 信息嵌入到程序清单中。

创建映射文件

包括映射文件中的指定信息

合并节

指定 MIDL 命令行选项

取消创建 .NET Framework 程序集

在解析外部引用时忽略所有(或指定的)默认库

创建纯资源 DLL

取消显示启动版权标志

将可执行文件标记为经测试与 Windows 数据执行保护功能兼容。

控制 LINK 优化

按预先确定的顺序将 COMDAT 放置到图像中

指定输出文件名

创建程序数据库 (PDB) 文件

创建没有私有符号的程序数据库 (PDB) 文件

为按配置文件优化指定 .pgd 文件。

生成一个可与“性能工具”探查器结合使用的输出文件。

在 .exe 文件头中设置校验和

指定图像将包含安全异常处理程序表。

重写节的属性

设置堆栈的大小(以字节为单位)

将 MS-DOS 存根 (stub) 程序附加到 Win32 程序

通知操作系统如何运行 .exe 文件

通知操作系统在运行链接器输出之前将其复制到一个交换文件

允许指定链接器生成的类型库的资源 ID

指定 .tlb 文件和其他 MIDL 输出文件的名称

创建专为在终端服务器下运行而设计的应用程序

打印链接器进度消息

分配版本号

将链接器警告视为错误。

 

 

4、参考资料

 

有关更多信息,请参见、 、.

转载于:https://www.cnblogs.com/songtzu/archive/2013/01/12/2857358.html

你可能感兴趣的文章
2019年春季学期第四周作业
查看>>
MVC4.0 利用IActionFilter实现简单的后台操作日志功能
查看>>
rotate the clock
查看>>
bugku 变量
查看>>
数据库01 /Mysql初识以及基本命令操作
查看>>
数据库02 /MySQL基础数据类型以及多表之间建立联系
查看>>
Python并发编程04/多线程
查看>>
CF461B Appleman and Tree
查看>>
CF219D Choosing Capital for Treeland
查看>>
杂七杂八的小笔记本
查看>>
51Nod1353 树
查看>>
CF1215E Marbles
查看>>
BZOJ2339 HNOI2011卡农(动态规划+组合数学)
查看>>
octave基本操作
查看>>
axure学习点
查看>>
WPF文本框只允许输入数字[转]
查看>>
dom4j 通用解析器,解析成List<Map<String,Object>>
查看>>
第一个项目--用bootstrap实现美工设计的首页
查看>>
使用XML传递数据
查看>>
TYVJ.1864.[Poetize I]守卫者的挑战(概率DP)
查看>>