從Linux到Windows必知

構(gòu)建體系

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

Visual C/C++

VisualStudio

微軟的原生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

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

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>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容