2010-11-14 22 views
0

我有以下代碼:未指定庫,但printf鏈接到C++程序中?

#include <stdio.h> 

int main() 
{ 
    printf ("hello world\n"); 
    return 0; 
} 

使用MSVC++ 10.0在Windows 7的x86,我編譯它在命令行上,如下所示:

cl.exe simple.cpp 

這產生simple.exe(編譯器自動調用鏈接器),並且可執行文件按預期顯示「hello world」消息。當我查看可執行文件w/depend.exe時,它顯示kernel32.dll是唯一的依賴項。當我dumpbin kernel32.dll庫的內容時,沒有顯示printf。

VC++是否採用某種優化方式,使printf以某種方式直接包含在最終的可執行文件中?如果是這樣,那麼,它是如何記錄在任何地方?

提前感謝 -

託德

回答

1

libc.lib不再使用。

在VC++ 10中靜態或動態包含C運行時庫(CRT)的選項記錄在here中。您可以在「項目選項」中選擇您需要的項目。

+0

感謝您的URL,無法在MSDN迷宮中自行找到它。 – Sabuncu 2010-11-14 16:19:17

1

的printf(實際上fprintf中到標準輸出),以及其他的「標準」函數malloc,退出等靜態與LIBC.LIB的聯繫,這就是爲什麼你不要將它視爲任何地方的DLL。

+0

正如史蒂夫在下面說的,libc不再可用,它的多線程版本libcmt現在被使用,但它的想法是一樣的 - 它是靜態構建的,並且不使用dll – Marin 2010-11-14 15:47:32

+0

謝謝,我很欣賞響應。 – Sabuncu 2010-11-14 16:20:01

2

MS VC將「默認」庫的名稱嵌入到大多數目標文件中。除非您使用鏈接器的-nodefaultlib選項另外指定,否則該庫(或那些庫)將被鏈接。如果你自己使用它,它不鏈接任何默認庫。您還可以指定-nodefaultlib:mylib.lib之類的東西,在這種情況下,它會鏈接除您在此指定的以外的所有默認庫

要使用你的例子,如果你使用:

cl simple.c 

它會正確地編譯和鏈接。但是,如果你使用:

cl simple.c -link -nodefaultlib 

您將獲得:

simple.obj:錯誤LNK2019:無法解析的外部符號的printf函數主要
鏈接引用:錯誤LNK2001:無法解析的外部符號mainCRTStartup
simple.exe:致命錯誤LNK1120:2周無法解析的外部

只要是完整的,你也可以使用編譯器的/Zl切換到創建對象而不嵌入任何庫的名稱。這主要是爲了創建靜態庫,因此它們不會嵌入與庫的名稱衝突,但是您會構建使用庫的代碼。

+0

我嘗試了-nodefaultlib並得到了與您所顯示的完全相同的輸出。謝謝。 – Sabuncu 2010-11-14 19:41:35