錯誤 1 error LNK2005: __cexit 已經在 MSVCRTD.lib(MSVCR100D.dll) 中定義 d:\ProjectArchive\LibH264\LibH264\libcmtd.lib(crt0dat.obj) LibH264
錯誤 2 error LNK2005: __amsg_exit 已經在 MSVCRTD.lib(MSVCR100D.dll) 中定義 d:\ProjectArchive\LibH264\LibH264\libcmtd.lib(crt0dat.obj) LibH264
錯誤 3 error LNK2005: __initterm_e 已經在 MSVCRTD.lib(MSVCR100D.dll) 中定義 d:\ProjectArchive\LibH264\LibH264\libcmtd.lib(crt0dat.obj) LibH264
錯誤 4 error LNK2005: ___CppXcptFilter 已經在 MSVCRTD.lib(MSVCR100D.dll) 中定義 d:\ProjectArchive\LibH264\LibH264\libcmtd.lib(winxfltr.obj) LibH264
錯誤 5 error LNK2005: __encoded_null 已經在 MSVCRTD.lib(MSVCR100D.dll) 中定義 d:\ProjectArchive\LibH264\LibH264\libcmtd.lib(tidtable.obj) LibH264
錯誤 6 error LNK2005: __malloc_dbg 已經在 MSVCRTD.lib(MSVCR100D.dll) 中定義 d:\ProjectArchive\LibH264\LibH264\libcmtd.lib(dbgheap.obj) LibH264
錯誤 7 error LNK2005: __free_dbg 已經在 MSVCRTD.lib(MSVCR100D.dll) 中定義 d:\ProjectArchive\LibH264\LibH264\libcmtd.lib(dbgheap.obj) LibH264
錯誤 8 error LNK2005: __CrtSetCheckCount 已經在 MSVCRTD.lib(MSVCR100D.dll) 中定義 d:\ProjectArchive\LibH264\LibH264\libcmtd.lib(dbgheap.obj) LibH264多線程
這種錯誤常常會碰到吧?呵呵。。。。函數
解決了這個問題的方法就是修改一下編譯選項,將/MD選項改成/MT選項,最終的可執行文件就不會包含對那些VC運行時DLL的引用了,能夠很方便的發佈和部署。首先讓咱們來看下這個雲遮霧罩的編譯開關到底是幹什麼的?MSDN中的描述以下:spa
/MD命令行
使應用程序使用運行時庫的多線程並特定於 DLL 的版本。定義 _MT 和 _DLL,並使編譯器將庫名 MSVCRT.lib 放入 .obj 文件中。線程
用此選項編譯的應用程序靜態連接到 MSVCRT.lib。該庫提供容許連接器解析外部引用的代碼層。實際工做代碼包含在 MSVCR90.DLL, 中,該庫必須在運行時對於與 MSVCRT.lib 連接的應用程序可用。調試
當 /MD 與 _STATIC_CPPLIB 預處理器定義 (/D_STATIC_CPPLIB) 一塊兒使用時,您的應用程序將與靜態多線程標準 C++ 庫 (libcpmt.lib) 而非動態版本 (msvcprt.lib) 連接,但仍經過 msvcrt.lib 動態連接到主 CRT。code
請注意,不支持 _STATIC_CPPLIB 預處理器定義和 /clr 或 /clr:pure 編譯器選項的組合。有關 /clr 選項的限制的更多信息,請參見 /clr 限制。orm
/MDd部署
定義 _DEBUG、_MT 和 _DLL,並使應用程序使用運行時庫的調試多線程並特定於 DLL 的版本。它還使編譯器將庫名 MSVCRTD.lib 放入 .obj 文件中。編譯器
/MT
使應用程序使用運行時庫的多線程靜態版本。定義 _MT 並使編譯器將庫名 LIBCMT.lib 放入 .obj 文件中,以便連接器使用 LIBCMT.lib 解析外部符號。
/MTd
定義 _DEBUG 和 _MT。此選項還使編譯器將庫名 LIBCMTD.lib 放入 .obj 文件中,以便連接器使用 LIBCMTD.lib 解析外部符號。
/LD
建立 DLL。
將 /DLL 選項傳遞到連接器。連接器查找 DllMain 函數,但並不須要該函數。若是沒有編寫 DllMain 函數,連接器將插入返回 TRUE 的 DllMain 函數。
連接 DLL 啓動代碼。
若是命令行上未指定導出 (.exp) 文件,則建立導入庫 (.lib);將導入庫連接到調用您的 DLL 的應用程序。
將 /Fe(命名 EXE 文件) 解釋爲命名 DLL 而不是 .exe 文件;默認程序名成爲基名稱.dll 而不是基名稱.exe。
除非顯式指定 /MD,不然將暗指 /MT。
/LDd
建立調試 DLL。定義 _MT 和 _DEBUG。
看到這裏,我恍然大悟,原來這個開關就是控制這個C運行時庫的引用方式的,真是踏破鐵鞋無覓處得來全不費工夫。
固然到這裏先別忙着去修改你的項目屬性中關於這個開關的選項,由於當你的項目也是一個LIB時,若是使用了/MT或/MTd選項時,最終的靜態LIB中就會出現LIBCMT.lib中的大量符號,致使在別的項目引用你的這個靜態LIB時出現重複定義符號而沒法連接的錯誤,怎麼解決呢?其實繼續看MSDN中的幫助就能夠獲得答案:
傳遞給連接器的給定調用的全部模塊都必須使用相同的運行時庫編譯器選項(/MD、/MT、/LD)進行編譯。
呵呵,原來如此,全部的模塊保持一致就完了,可是靜態的LIB貌似仍是沒法引用,問題依舊怎麼辦呢?
那就是在引用了你本身的使用/MT或/MTd選項編譯生成的靜態LIB的項目中,不但指定對應的/MT或/MTd選項,並且須要忽略LIBCMT.lib庫便可。
總結下來,《VC++語言參考手冊》中其實早就描述過這個問題了,這本書有時間能夠再看看。