前言
寫了一個Dll注入工具,結果發現程序在其他機器上會出現丟失“MSVCR100D.dll”。這個dll是vs2010自帶的動態鏈接庫,如果在沒安裝vs2010運行庫的電腦中使用就會出現這種情況。我在網上搜了一下並總結所涉及的知識。
/MD , /MDd 與 /MT , /MTd
這些是程序在被編譯器編譯時的所傳入的參數,不同的參數編譯器會做出不同的操作。
/MD
/MD的意思是多線程DLL的版本,編譯器會把MSVCRT.lib放到.OBJ文件中,然后鏈接器會通過MSVCRT.lib解析外部符號。其是動態編譯,也就是程序將相應dll的信息保存在導入表中,如此一來程序在運行的時候就必須依賴於相應的dll。如果缺少相應的dll將無法運行,如果是vs2010編寫的程序也就會出現缺失MSVCR100.dll。
/MDd
/MDd和/MD差不多,只不過其是在調試狀態下。所以鏈接器會將MSVCRTD.lib放到.OBJ文件中。如果是vs2010編寫的程序其將依賴於MSVCR100D.dll。
/MT
/MT的意思是多線程靜態的版本。編譯器會把靜態多線程標准 C++ 庫(libcpmt.lib)放到 .OBJ文件中,然后鏈接器通過libcpmt.lib解析外部符號。其屬於靜態編譯,所以會將那些本來是在dll中導出的函數都整合到exe文件中。這樣exe文件就會變大,其在運行的時候也不需要去依賴於相應的動態鏈接庫。在程序的輸入表中也不會有相應的dll信息。
/MTd
/MTd 與 /MT相似,只不過其實調試狀態下的。編譯器會將libcpmtd.lib放到.OBJ文件中,鏈接器通過libcpmtd.lib解析外部符號。
總結
所以為了讓程序不依賴與MSVCRT100D.dll或者是MSVCRT100.dll,我們需要在用VS2010編寫程序的時候將編譯選項設置為 /MT或/MTd。