天天看點

深入探究VC —— 連結器link.exe(4)

在程式編譯完成後,生成的檔案是以.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對檔案格式的判斷不是根據檔案擴充名,而是判斷檔案的内容。

比如之前【深入探究VC —— 編譯器cl.exe(1)】代碼中:

// File   Name: Hello.c   

// Description: First Win32 Application   

// by Koma 2009-11-18 22:05   

#include <windows.h>   

#pragma comment(lib,"user32.lib")   

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pszCmdLine, int cmdShow)   

{   

    MessageBox(NULL,"Hello World !","Test",MB_OK);   

    return 0;   

}

Hello.c完成編譯後會生成Hello.obj檔案,然後将Hello.obj與系統庫檔案連結起來,最終生成可執行檔案。指令行參數為:

link Hello.obj /subsystem:windows

注意,在之前【深入探究VC —— 編譯器cl.exe(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可執行檔案編譯與連結的内部原理,請自行查閱相關資料吧!)

選項

 用途

@

 指定響應檔案

/ALIGN

 指定每一節的對齊方式

/ALLOWBIND

 指定 DLL 不能綁定

/ALLOWISOLATION

 指定清單查找的行為。

/ASSEMBLYDEBUG

 将 DebuggableAttribute 添加到托管映像中。

/ASSEMBLYLINKRESOURCE

 建立指向托管資源的連結。

/ASSEMBLYMODULE

 指定應将 Microsoft 中間語言 (MSIL) 子產品導入到程式集中

/ASSEMBLYRESOURCE

 将托管資源檔案嵌入到程式集

/BASE

 為程式設定基址

/CLRIMAGETYPE

 設定 CLR 映像的類型(IJW 映像、純映像或安全映像)。

/CLRSUPPORTLASTERROR

 保留通過 P/Invoke 機制調用的函數的上一個錯誤代碼。

/CLRTHREADATTRIBUTE

 指定要應用于 CLR 程式入口點的線程屬性。

/CLRUNMANAGEDCODECHECK

 /CLRUNMANAGEDCODECHECK 指定連結器是否将 SuppressUnmanagedCodeSecurity 屬性應用于連結器生成的、從托管代碼調用到本機 DLL 中的 PInvoke 存根 (stub)。

/DEBUG

 建立調試資訊

/DEF

 将子產品定義 (.def) 檔案傳遞到連結器

/DEFAULTLIB

 在解析外部引用時搜尋指定的庫

/DELAY

 控制 DLL 的延遲加載

/DELAYLOAD

 導緻延遲加載指定的 DLL

/DELAYSIGN

 對程式集進行部分簽名。

/DLL

 生成 DLL

/DRIVER

 建立 Windows NT 核心模式驅動程式

/DYNAMICBASE

 使用 Windows Vista 的位址空間布局随機化 (ASLR) 功能,指定是否生成可在加載時随機重新設定基址的可執行檔案映像。

/ENTRY

 設定起始位址

/errorReport

 向 Microsoft 報告内部連結器錯誤。

/EXPORT

 導出函數

/FIXED

 建立隻能在其首選基址加載的程式

/FORCE

 強制完成連結,即使符号無法解析或已定義多次

/FUNCTIONPADMIN

 建立可熱修補的映像。

/HEAP

 設定堆的大小(以位元組為機關)

/IDLOUT

 指定 .idl 檔案和其他 MIDL 輸出檔案的名稱

/IGNOREIDL

 防止将屬性資訊處理到 .idl 檔案中

/IMPLIB

 重寫預設的導入庫名

/INCLUDE

 強制符号引用

/INCREMENTAL

 控制增量連結

/KEYCONTAINER

 指定用來為程式集簽名的密鑰容器。

/KEYFILE

 指定用來為程式集簽名的密鑰或密鑰對。

/LARGEADDRESSAWARE

 通知編譯器應用程式支援大于 2 GB 的位址

/LIBPATH

 允許使用者重寫環境庫路徑

/LTCG

 指定連結時代碼生成

/MACHINE

 指定目标平台

/MANIFEST

 建立并行清單檔案。

/MANIFESTDEPENDENCY

 在清單檔案中指定 <dependentAssembly> 節。

/MANIFESTFILE(命名清單檔案)

 更改清單檔案的預設名稱。

/MANIFESTUAC

 指定是否将使用者帳戶控制 (UAC) 資訊嵌入到程式清單中。

/MAP

 建立映射檔案

/MAPINFO

 包括映射檔案中的指定資訊

/MERGE

 合并節

/MIDL

 指定 MIDL 指令行選項

/NOASSEMBLY

 取消建立 .NET Framework 程式集

/NODEFAULTLIB

 在解析外部引用時忽略所有(或指定的)預設庫

/NOENTRY

 建立純資源 DLL

/NOLOGO

 取消顯示啟動版權标志

/NXCOMPAT

 将可執行檔案标記為經測試與 Windows 資料執行保護功能相容。

/OPT

 控制 LINK 優化

/ORDER

 按預先确定的順序将 COMDAT 放置到圖像中

/OUT

 指定輸出檔案名

/PDB

 建立程式資料庫 (PDB) 檔案

/PDBSTRIPPED

 建立沒有私有符号的程式資料庫 (PDB) 檔案

/PGD

 為按配置檔案優化指定 .pgd 檔案。

/PROFILE

 生成一個可與“性能工具”探查器結合使用的輸出檔案。

/RELEASE

 在 .exe 檔案頭中設定校驗和

/SAFESEH

 指定圖像将包含安全異常處理程式表。

/SECTION

 重寫節的屬性

/STACK

 設定堆棧的大小(以位元組為機關)

/STUB

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

/SUBSYSTEM

 通知作業系統如何運作 .exe 檔案

/SWAPRUN

 通知作業系統在運作連結器輸出之前将其複制到一個交換檔案

/TLBID

 允許指定連結器生成的類型庫的資源 ID

/TLBOUT

 指定 .tlb 檔案和其他 MIDL 輸出檔案的名稱

/TSAWARE

 建立專為在終端伺服器下運作而設計的應用程式

/VERBOSE

 列印連結器進度消息

/VERSION

 配置設定版本号

/WX

 将連結器警告視為錯誤。

4、參考資料

微軟官方MSDN幫助文檔

有關更多資訊,請參見編譯器控制的 LINK 選項、 設定連結器選項、有關生成的常見問題.

繼續閱讀