鏈接錯誤:error LNK2019:無法解析的外部符號 __CrtDbgReportW——庫衝突(libcmt.lib和libcmtd.lib)

error LNK2019: 無法解析的外部符號

這種情況一般都是函數只找到聲明但沒有實現,或者是少了鏈接庫
1.看看聲明和函數定義是否一致
2.看看工程是否包含.h .cpp文件
3.查找是否缺少定義該函數的鏈接,庫

在VC2008中調試一個可執行文件時代碼生成通過,但是連接時編譯器報錯

        1>正在鏈接...
        1>   正在創建庫 .\Debug/djzdt.lib 和對象 .\Debug/djzdt.exp
        1>djzdt.exp : warning LNK4070: .EXP 中的 /OUT:cassdjzdt.dll 指令與輸出文件名“D:\djzdt.arx”不同;忽略指令
        1>atlsd.lib(Externs.obj) : error LNK2019: 無法解析的外部符號 __CrtDbgReportW,該符號在函數 "void __stdcall                      ATL::AtlThrowImpl(long)" (?AtlThrowImpl@ATL@@YGXJ@Z) 中被引用
        1>atlsd.lib(AtlDebugAPI.obj) : error LNK2001: 無法解析的外部符號 __CrtDbgReportW
        1>atlsd.lib(Allocate.obj) : error LNK2001: 無法解析的外部符號 __CrtDbgReportW
        1>atlsd.lib(AtlTraceModuleManager.obj) : error LNK2001: 無法解析的外部符號 __CrtDbgReportW
        1>atlsd.lib(Externs.obj) : error LNK2019: 無法解析的外部符號 __CrtDbgReport,該符號在函數 "void __cdecl `dynamic initializer        for 'public: static class ATL::CTrace ATL::CTrace::s_trace''(void)" (??__E?s_trace@CTrace@ATL@@2V12@A@@YAXXZ) 中        被引用
        1>atlsd.lib(AtlTraceModuleManager.obj) : error LNK2001: 無法解析的外部符號 __CrtDbgReport

        1>D:\djzdt.arx : fatal error LNK1120: 2 個無法解析的外部命令


開始以爲是原文件缺失可是在工程中查找CrtDbgReportW,但是沒有找到源文件位置,於是上網搜,就找到了。

方法一:
最終是單線程/多線程的問題,描述如下
運行時庫現在包含可防止混合不同類型的指令。如果試圖在同一個程序中使用不同類型的運行時庫或使用調試和非調試版本的運行時庫,則將收到此警告。例如,如果編譯一個文件以使用一種運行時庫,而編譯另一個文件以使用另一種運行時庫(例如單線程運行時庫對多線程運行時庫),並試圖鏈接它們,則將得到此警告。應將所有源文件編譯爲使用同一個運行時庫。有關更多信息,請參見使用運行時庫(/MD、/MT 和 /LD)編譯器選項。
 
 解決方案:(不是很多時候不成功一個好辦法!!!)
項目屬性,在“配置屬性-->C/C++-->代碼生成-->運行時庫”中將“多線程(/MT)”修改爲“多線程調試(/MTd)”。
或者Project-->Properties-->Configuration Properties--> C/C++--> Code Generation -->Runtime Library -->Multi-threaded (/MT)  改爲 Multi-threaded Debug (/MTd)

部分參考:http://www.cnblogs.com/lgydqy/archive/2012/02/16/2353925.html

方法二:

在同一個項目中,所有的源文件必須鏈接相同的C運行時庫。如果某一文件用了Multithreaded DLL版本,而其他文件用了Single-Threaded或者Multithreaded版本的庫,也就是說用了不同的庫,就會導致這個警告的出現。

參考:http://blog.csdn.net/redline2005/article/details/6313703

  lib之間有衝突。需要刪除導入的一些libs  

   版 本 類 型 使用的library 被忽略的library
R  Release 單線程 libc.lib libcmt.lib, msvcrt.lib, libcd.lib, libcmtd.lib, msvcrtd.lib
多線程 libcmt.lib libc.lib, msvcrt.lib, libcd.lib, libcmtd.lib, msvcrtd.lib
使用DLL的多線程 msvcrt.lib libc.lib, libcmt.lib, libcd.lib, libcmtd.lib, msvcrtd.lib
D   Debug 單線程 libcd.lib libc.lib, libcmt.lib, msvcrt.lib, libcmtd.lib, msvcrtd.lib
多線程 libcmtd.lib libc.lib, libcmt.lib, msvcrt.lib, libcmtd.lib, msvcrtd.lib
使用DLL的多線程 msvcrtd.lib libc.lib, libcmt.lib, msvcrt.lib, libcd.lib, libcmtd.lib

解決方案:工程-->屬性-->鏈接器-->輸入-->忽略特定庫:將libcmt。

eg:編譯Release版本的單線程的工程,在linker的命令行加入如下的參數: /NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:libcd.lib /NODEFAULTLIB:libcmtd.lib /NODEFAULTLIB:msvcrtd.lib


如果還不行,用release版試,或者把debug版本中預編譯頭的_debug去掉

因爲

#ifdef _DEBUG  (只有debug版本纔會執行這個,release不會執行所以沒錯,把預編譯頭去掉_debug肯定能過)

int _CrtDbgReportW( 
   int reportType,
   const wchar_t *filename,
   int linenumber,
   const wchar_t *moduleName,
   const wchar_t *format,
   ... 
)
{
return 0;
}
#endif

///以下參考
#include <crtdbg.h>
庫的話 msvcrtd.lib 
最好不直接使用 _CrtDbgReport, 用 _ASSERT
在Debug模式下 _ASSERT 被定義爲


?
 
#define _ASSERT(expr) \
        do if (!(expr) && \
                (1 == _CrtDbgReport(_CRT_ASSERT, __FILE__, __LINE__, NULL, NULL))) \
             _CrtDbgBreak(); } while (0)

在非Debug模式下 
C/C++ code
?
1
#define _ASSERT(expr) ((void)0)
所以使用 _ASSERT 包含crtdbg.h 後就不會報編譯連接錯誤
加上這個才能編譯過。。。



發佈了15 篇原創文章 · 獲贊 4 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章