癥狀:
當 C 運行時(shí) (CRT) 庫和 Microsoft 基礎類(lèi) (MFC) 庫的鏈接順序有誤時(shí),可能會(huì )出現以下某個(gè) LNK2005 錯誤:
nafxcwd.lib(afxmem.obj) :error LNK2005:
"void * __cdecl operator new(unsigned int)"(2@YAPAXI@Z) already
defined in LIBCMTD.lib(new.obj)
nafxcwd.lib(afxmem.obj) :error LNK2005:
"void __cdecl operator delete(void *)"(3@YAXPAX@Z) already defined
in LIBCMTD.lib(dbgnew.obj)
nafxcwd.lib(afxmem.obj) :error LNK2005:
"void * __cdecl operator new(unsigned int,int,char const *,int)"
(2@YAPAXIHPBDH@Z) already defined in LIBCMTD.lib(dbgnew.obj)
mfcs40d.lib(dllmodul.obj):error LNK2005:_DllMain@12 already defined in
MSVCRTD.LIB (dllmain.obj)
mfcs42d.lib(dllmodul.obj):error LNK2005:_DllMain@12 already defined in
msvcrtd.lib(dllmain.obj)
原因
CRT 庫對 new、delete 和 DllMain 函數使用弱外部鏈接。MFC 庫也包含 new、delete 和 DllMain 函數。這些函數要求先鏈接 MFC 庫,然后再鏈接 CRT 庫。
解決方案:
解決該問(wèn)題有兩種方法:第一種解決方案涉及到強制鏈接程序按照正確的順序鏈接庫。第二種解決方案是讓您查找導致問(wèn)題的模塊并糾正它。
解決方案一:強制鏈接程序按照正確的順序鏈接庫
1. 在“生成”菜單上,單擊“設置”。
2. 在“項目設置”對話(huà)框的“以下項目的設置”視圖中,單擊以選中出現鏈接錯誤的項目配置。
3. 在“鏈接”選項卡上,單擊以選中“類(lèi)別”組合框中的“INPUT”。
4. 在“要忽略的庫”中,插入庫名(例如,Nafxcwd.lib;Libcmtd.lib)。
注意:等效的鏈接程序命令行是:/NOD:<library name>。
5. 在“對象/庫模塊”框中,插入庫名。必須確保這些庫按順序列出,且作為命令行中的前兩個(gè)庫(例如,Nafxcwd.lib 和 Libcmtd.lib)列出。
要在 Visual C++ .NET 中設置該選項,請閱讀“設置 Visual C++ 項目屬性”聯(lián)機幫助主題。
解決方案二:找到并糾正出現問(wèn)題的模塊
要查看當前的庫鏈接順序,請按照下列步驟操作: 1. 在“生成”菜單上,單擊“設置”。
2. 在“項目設置”對話(huà)框的“以下項目的設置”視圖中,單擊以選中出現鏈接錯誤的項目配置。
3. 在“鏈接”選項卡上,在“項目選項”框中鍵入 /verbose:lib。
4. 重新生成項目。在鏈接過(guò)程中,這些庫將在輸出窗口中列出。
狀態(tài):
這種現象是由設計導致的。
更多信息
使用 MFC 庫時(shí),務(wù)必先鏈接它們,然后再鏈接 CRT 庫。這可以通過(guò)確保項目中的每個(gè)文件都首先包含 Msdev\Mfc\Include\Afx.h 來(lái)完成。直接包含 (#include <Afx.h>) 或間接包含 (#include <Stdafx.h>) 都可以。Afx.h 包含文件會(huì )通過(guò)使用 #pragma comment (lib,"<libname>") 指令來(lái)強制采用庫的正確順序。
如果源文件的擴展名為 .c,或者該文件的擴展名為 .cpp 但不使用 MFC,則可以創(chuàng )建一個(gè)較小的頭文件 (Forcelib.h) 并將其放在模塊的頂端。這個(gè)新頭文件可確保按照正確的順序搜索庫。
Visual C++ 不包含該頭文件。要創(chuàng )建此文件,請按照下列步驟操作:
1. 打開(kāi) Msdev\Mfc\Include\Afx.h。
2. 選定 #ifndef _AFX_NOFORCE_LIBS 和 #endif //!_AFX_NOFORCE_LIBS 之間的行。
3. 將選定部分復制到 Windows 剪貼板。
4. 創(chuàng )建一個(gè)新文本文件。
5. 將剪貼板的內容粘貼到這個(gè)新文件中。
6. 將該文件另存為 Msdev\Mfc\Include\Forcelib.h。
在 Visual C++ .NET 中重現問(wèn)題的步驟
1. 啟動(dòng) Microsoft Visual Studio .NET。
2. 在“文件”菜單上,指向“新建”,然后單擊“項目”。
3. 單擊“項目類(lèi)型”下的“Visual C++ 項目”,然后單擊“模板”下的“MFC 應用程序”。
4. 在“名稱(chēng)”文本框中,鍵入 Q148652。
5. 在“位置”文本框中,鍵入 C:\Test,然后單擊“確定”。
6. 在“MFC 應用程序向導”對話(huà)框中,單擊“應用程序類(lèi)型”。
7. 單擊“應用程序類(lèi)型”下的“基于對話(huà)框”,然后單擊“使用 MFC”下的“使用靜態(tài)庫中的 MFC”。
8. 單擊“完成”。
9. 在解決方案資源管理器中,選擇“源文件”下的全部三個(gè) .cpp 文件。
10. 右鍵單擊三個(gè)選定的文件,然后單擊“刪除”。
11. 右鍵單擊“源文件”,指向“添加”,然后單擊“添加新項”。
12. 單擊“模板”下的“C++ 文件”。在“名稱(chēng)”文本框中,鍵入 Aa。單擊“打開(kāi)”。
13. 將以下代碼粘貼到 Aa.cpp 中:int test(){new int; return 1;}
14. 右鍵單擊“源文件”,指向“添加”,然后單擊“添加現有項”。
15. 選擇以下文件: ? Q148652.cpp ? Q148652Dlg.cpp ? stdafx.cpp
16. 單擊“打開(kāi)”。
17. 您在第 15 步中選擇的文件將出現在“源文件”下。
18. 選擇“源文件”下的全部四個(gè) .cpp 文件。
19. 右鍵單擊四個(gè)選定的 .cpp 文件,然后單擊“屬性”。
20. 展開(kāi)“配置屬性”,然后展開(kāi)“C/C++”。
21. 單擊“預編譯頭”。
22. 將“創(chuàng )建/使用預編譯頭”屬性設置為“不使用預編譯頭”。單擊“確定”。
23. 在“生成”菜單上,單擊“重新生成解決方案”。
--------------------------------------------------------------------------------
這篇文章中的信息適用于:
Microsoft Visual C++ 4.0 標準版
Microsoft Visual C++ 4.1 Subscription
Microsoft Visual C++ 5.0 企業(yè)版
Microsoft Visual C++ 6.0 企業(yè)版
Microsoft Visual C++ 5.0 專(zhuān)業(yè)版
Microsoft Visual C++ 6.0 專(zhuān)業(yè)版
Microsoft Visual C++ 6.0 標準版
Microsoft Visual C++ .NET 2002 標準版
Microsoft Visual C++ .NET 2003 Standard Edition
聯(lián)系客服