openfans.org-開源愛好者社區

最近c++程序寫的比較多,發現以前設計的一些問題,原則是這樣使用c++就不要使用c,因爲c的文件不會被預編譯,你必須在工程中c++頁設置Not using。。。
因爲沒有預編譯,有時候要引入windows.h文件。有一次寫jni,一個從linux轉過來的哥們,不會用c++,使用c程序,使用動態數組的技術,根據函數傳來的參數,初始化數組的大小,當然不是static的,但是這個vc編譯不過去,使用gcc編譯,編譯cpp我們用g++,還得在函數上寫明extern "C"。
mingw還沒有make,無法寫mak文件, 全是手工編譯連接,後來發現一個辦法,c寫的程序作爲一個獨立的工程,編譯爲.a lib文件,c++引用,vc的工程也是如此,cpp和c分開使用,mfc的cpp和其他cpp的文件也要分工程,這樣用利於編譯。
還有在cpp中少用c的語法,例如傳遞指針不如傳遞引用,否則你的代碼就是指針和引用起飛,c和c++共天一色,使用stl就不必使用c的char數組。包含stdafx.h就自己包含windows.h和afx.h。
當 C 運行時 (CRT) 庫和 Microsoft 基礎類 (MFC) 庫的鏈接順序有誤時,可能會出現以下 LNK2005 錯誤之一:
vc的crt的動態庫是mscrt.dll,borland的bcb是borlandmm.dll,vc開始編譯時(即生成makefile時),將源文件名按字母排序後,依次處理;一邊編譯一邊決定需要哪些缺省庫。 它的這些習慣有時會造成奇怪的編譯錯誤,例如項目中有兩個文件:
dateutil.c 使用c的函數
MYApp.cpp 使用了MFC的c函數。
編譯器先處理dateutil.c,然後覺得需要link一個C Runtime庫,根據項目設置選擇了LIBCMTD.lib。
然後又處理MYApp.cpp,因爲要用MFC,link nafxcwd.lib。
最後link的時候,就會出現以下衝突:
nafxcwd.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete(void *)" (??3@YAXPAX@Z) already defined in LIBCMTD.lib(dbgdel.obj)
其實,如果先link nafxcwd.lib,再link LIBCMTD.lib,就不會產生衝突。
解決這類問題有兩個辦法。
1、將需要link C Runtime庫的文件(dateutil.c)的名字改大一些,讓它排在後面。
2、在settings->link->input的Objects/library modules中設置nafxcwd.lib LIBCMTD.lib,強制指定庫的順序。也可以順利編譯。
總結一下:在發生缺省庫衝突時,可以通過手工設置缺省庫的順序來解決,正確的順序應該是:
MFC庫、CRT動態鏈接版本的導入庫、CRT靜態庫。
CRT是C RunTime庫的縮寫。
微軟的說法
原因
CRT 庫對 new、delete 和 DllMain 函數使用弱外部鏈接。MFC 庫也包含 new、delete 和 DllMain 函數。這些函數要求先鏈接 MFC 庫,然後再鏈接 CRT 庫。

回到頂端
解決方案
該問題有兩種解決方法。第一種方法是強制鏈接器按照正確的順序鏈接庫。第二種方法是由您親自查找導致問題的模塊並糾正它。
注意:下列步驟基於 Visual C++ 6.0 進行。
回到頂端
解決方案一:強制鏈接器按照正確的順序鏈接庫1. 在“項目”菜單上,單擊“設置”。
2. 在“項目設置”對話框的“以下項目的設置”視圖中,單擊以選中出現鏈接錯誤的項目配置。
3. 在“鏈接”選項卡上,單擊以選中“類別”組合框中的“輸入”。
4. 在“忽略庫”框中,插入庫名(例如,Nafxcwd.lib;Libcmtd.lib)。
注意:等效的鏈接器命令行是:/NOD:。
5. 在“對象/庫模塊”框中,插入庫名。必須確保這些庫按順序列出,而且是行中的前兩個庫(例如,Nafxcwd.lib 和 Libcmtd.lib)。
解決方案二:找到並糾正出現問題的模塊
要查看當前的庫鏈接順序,請按照下列步驟操作: 1. 在“項目”菜單上,單擊“設置”。
2. 在“項目設置”對話框的“以下項目的設置”視圖中,單擊以選中出現鏈接錯誤的項目配置。
3. 在“鏈接”選項卡上的“項目選項”框中鍵入 /verbose:lib。
4. 重新生成項目。在鏈接過程中,這些庫將在輸出窗口中列出。
使用 MFC 庫時,務必先鏈接它們,然後再鏈接 CRT 庫。這可以通過確保項目中的每個文件都首先包含 Msdev/Mfc/Include/Afx.h 來完成。直接包含 (#include ) 或間接包含 (#include ) 都可以。Afx.h 包含文件會通過使用 #pragma comment (lib,"") 指令來強制採用庫的正確順序。
如果源文件的擴展名爲 .c,或者該文件的擴展名爲 .cpp 但不使用 MFC,則可以創建一個較小的頭文件 (Forcelib.h) 並將其放在模塊的頂端。這個新的頭文件可確保按照正確的順序搜索庫。
Visual C++ 不包含該頭文件。要創建此文件,請按照下列步驟操作: 1. 打開 Msdev/Mfc/Include/Afx.h。
2. 選定 #ifndef _AFX_NOFORCE_LIBS 和 #endif //!_AFX_NOFORCE_LIBS 之間的行。
3. 將選定部分複製到 Windows 剪貼板。
4. 創建一個新文本文件。
5. 將剪貼板的內容粘貼到這個新文件中。
6. 將該文件另存爲 Msdev/Mfc/Include/Forcelib.h。

回到頂端
在 Visual C++ .NET 中重現問題的步驟1. 啓動 Microsoft Visual Studio .NET。
2. 在“文件”菜單上,指向“新建”,然後單擊“項目”。
3. 單擊“項目類型”下的“Visual C++ 項目”,然後單擊“模板”下的“MFC 應用程序”。
4. 在“名稱”文本框中,鍵入 Q148652。
5. 在“位置”文本框中,鍵入 C:/Test,然後單擊“確定”。
6. 在“MFC 應用程序嚮導”對話框中,單擊“應用程序類型”。
7. 單擊“應用程序類型”下的“基於對話框”,然後單擊“MFC 的使用”下的“在靜態庫中使用 MFC”。
8. 單擊“完成”。
9. 在“解決方案資源管理器”中,選擇“源文件”下的全部三個 .cpp 文件。
10. 右鍵單擊三個選定的文件,然後單擊“刪除”。
11. 右鍵單擊“源文件”,指向“添加”,然後單擊“添加新項”。
12. 單擊“模板”下的“C++ 文件”。在“名稱”文本框中,鍵入 Aa。單擊“打開”。
13. 將以下代碼粘貼到 Aa.cpp 中:
int test(){new int; return 1;}
14. 右鍵單擊“源文件”,指向“添加”,然後單擊“添加現有項”。
15. 選擇以下文件: • Q148652.cpp
• Q148652Dlg.cpp
• stdafx.cpp
16. 單擊“打開”。
17. 您在第 15 步中選擇的文件將出現在“源文件”下。
18. 選擇“源文件”下的全部四個 .cpp 文件。
19. 右鍵單擊選定的四個 .cpp 文件,然後單擊“屬性”。
20. 展開“配置屬性”,然後展開“C/C++”。
21. 單擊“預編譯頭”。
22. 將“創建/使用預編譯頭”屬性設置爲“不使用預編譯頭”。單擊“確定”。
23. 在“生成”菜單上,單擊“重新生成解決方案”

本文轉自
http://cache.baidu.com/c?m=9d78d513d9d437a94f9be7690c66c0161c43f3632ba6db020ba78449e3732a4b5016e0ac56510777d0d27d1716df3d4b9df02173471450b68cbf8f5daccd85585f9f2644676df55662d00de88b182a9b66d618feae6afaa7b577d6b9d2a482160496075626c1e78b2d5c438c72ae4f70a5d2ca14542b47edbb4b23a8066029e87906e919eee1463254dea1ca5d3ac029d66a179cad31b03814bf15&p=8b2a9446bab150e41bb1c4710a1386&user=baidu
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章