
構(gòu)建體系
Windows平臺下構(gòu)建體系大致分三類:原生Visual C++、MinGW、Cygwin。下面詳細(xì)介紹著三種類型:
Visual C/C++

微軟的原生C/C++編譯器實現(xiàn),支持標(biāo)準(zhǔn)C和C++,當(dāng)然在標(biāo)準(zhǔn)C和C++基礎(chǔ)上有大量擴(kuò)展。另外,宇宙第一IDEVisual Studio提供了編輯、編譯、調(diào)試一體的解決方案,更是給編碼提供了很多的效率提升。隨著微軟.NET戰(zhàn)略的實施,VS逐漸成為.NET開發(fā)者的必要開發(fā)工具。
MinGW

MinGW(Minimal GUN for Windows)是一款windows軟件,旨在將GNU編譯工具鏈(gcc,binutil)移植到windows下,這樣可以在windows下使用gcc等工具構(gòu)建軟件。
一般MinGW需要配合MSYS來用。MSYS是一個Shell的windows移植版本,附帶有一些常用的命令和工具。這樣,有了MSYS,連configure都可以用了。MSYS實際上是下面要提到的Cygwin的一個早期分支派生出來的。
MSYS2是重寫了MSYS,并引入了pacman包管理工具。用MSYS2可以比較方便的搭建MinGW開發(fā)環(huán)境。
不過MinGW環(huán)境只是一系列編譯構(gòu)建工具的集合。對于在windows下開發(fā)程序,仍然需要使用windows原生的api。換句話說,可以理解為用MinGW代替Visual C/C++。
Cygwin

Cygwin在windows上實現(xiàn)了一層posix層,以便基于posix的程序移植到windows。因此,基于Cygwin,可以獲得更多的linux程序,并在windows使用。由于采用了中間層,因此運行效率相對原生的windows有些低,但是如果希望快速將linux程序移植到windows,是一個不錯的選擇。
Cygwin也派生出了上面提到的MSYS。
在發(fā)布基于Cygwin的程序時,需要帶上cygwin1.dll,作為依賴。
基于Cygwin我們可以在windows上使用熟悉的git vim make gcc等軟件,默認(rèn)的終端可以讓我們繼續(xù)使用/ 而不是\作為路徑分隔符。
工具
-
Denpendency Walker: 在linux下我們用ldd來查看程序的依賴,在windows下,我們需要Denpendency Walker -
Dumpbin: VS自帶的工具,用于查看庫的導(dǎo)入導(dǎo)出函數(shù) -
MSDN:Man是linux最重要的文檔參考工具,而在windows下,MSDN是必備的 -
《Windows via C/C++》:此書的地位相當(dāng)于APUE -
VS Command Line Tool:作為習(xí)慣了終端界面的linux程序員來說,可以更愿意使用編輯器+編譯器的模式,而并不喜歡使用vs的集成環(huán)境界面。那么我們需要找到VS附帶的Visual Studio命令行工具,用管理員身份打開它。這個bat腳本會為我們設(shè)置必要的編譯環(huán)境變量,然后在其中運行cl,link,nmake等編譯構(gòu)建命令才能有作用。
運行庫和庫文件
windows中也有類似glibc的C運行庫,以支撐C/C++編寫的程序得以運行。他們是MSVCRTxxd.dll和MSVCRTxx.dll,xx是版本號,筆者見過的有MSVCRT70.dll MSVCRT80.dll MSVCRT90.dll MSVCRT100.dll等,末尾的d表示是debug版本的運行庫還是release版本的運行庫。程序運行的時候究竟依賴哪個版本,取決于在編譯階段采用/MD還是/MDd編譯選項。
在windows中庫文件分兩種:
- .obj:對象文件,相當(dāng)于
.o。 - .dll:動態(tài)鏈接庫文件,類似
.so。程序在運行時才會加載和鏈接需要的dll。windows的一個方便的地方是,dll只需要在你的exe文件所在目錄中即可。 - .lib:靜態(tài)庫文件,類似
.a。程序在編譯時如果選擇靜態(tài)鏈接,那么.lib會用上。不過并不是所有的.lib都是靜態(tài)庫文件,還有一些.lib比較小,是作為.dll的導(dǎo)入庫存,沒有實際的二進(jìn)制代碼,只是一些符號表。也就是說如果你的程序依賴一個.dll,那么在編譯階段,編譯器要找到.dll相應(yīng).lib導(dǎo)入庫才能完成鏈接。而在運行時,只需要找到dll即可。
在windows中,可執(zhí)行文件采用PE格式封裝,相應(yīng)的,linux中采用ELF。
編寫或使用動態(tài)鏈接庫需要注意函數(shù)聲明方式。VC編譯器有一組特殊的聲明:__declspec(dllexport)和__declspec(dllimport)分別用于在dll中聲明為導(dǎo)出函數(shù),和在使用dll時聲明為dll導(dǎo)入函數(shù)。這種聲明會將函數(shù)名字添加__impl_前綴,因此如果不能配對使用的話,往往容易出現(xiàn)鏈接錯誤。
此外,__stdcall和__cdecl影響函數(shù)的入?yún)㈨樞颉?/p>