1.沒有解決的外部定義錯誤
xyView.obj : error LNK2001: unresolved external symbol "public: __thiscall CMyOCRInfo::CMyOCRInfo(void)" (??0CMyOCRInfo@@QAE@XZ)
可能是由於構造方法沒有實現代碼
2.沒有釋放 HBITMAP 句柄造成不能創建位圖的問題
2004.8.17
沒有及時的釋放 HBITMAP 句柄,當創建位圖數達到 30 時,出現 8 號錯誤,即內存不足
3.在調試窗口輸出信息
TRACE(s);
4.如果用向導新建類時只有自定義類型,則可能是因為 .clw 文件沒有生成,生成該文件即可
5.要注意變量的類型范圍,強制轉換可能會導致數據溢出;下面的示例將導致死循環:
for(byte i=0;i<256;i++){
... ...
}
注:由於 byte 類型的表示范圍為:0-255 ,因此 i 永遠不可能大於 255 ,所以導致死鎖
6.沒有包含 stdafx.h 導致的錯誤:
fatal error C1010: unexpected end of file while looking for precompiled header directive
在 .cpp 文件中包含 stdafx.h 文件即可
7.避免重復包含頭文件
#ifndef _INC_PUBLIC_H_32564987132178947
#define _INC_PUBLIC_H_32564987132178947
// 中間寫代碼
...
#endif
注:#ifndef 可以改為 #if !defined
8.出現重復定義錯誤,例如:
d:/program files/microsoft visual studio/vc98/include/dbdaoint.h(33) : error C2011: 'EditModeEnum' : 'enum' type redefinition
先檢查所有的 .h 文件中是否定義了 include "stdafx.h" ,刪之
再在所有的 .cpp 文件中搜索 stdafx ,看是否重復包含了 stdafx.h 文件,把重復的刪掉
又如:
RefImageDll.obj : error LNK2005: "int __cdecl GetCameraRefImageIndexOfID1(class CArray<class CCameraRefImage,class CCameraRefImage> &,int)" (?GetCameraRefImageIndexOfID1@@YAHAAV?$CArray@VCCameraRefImage@@V1@@@H@Z) already defined in InterFaceFile.obj
是因為在 .h 文件中定義了一個函數,且做了完整的實現,因此被多個文件包含時就會出現重復定義錯誤,解決的方法是
把該函數定義成 inline ,這樣就不再是一個函數而直接采用一段代碼替換了,如:
int inline GetAge(){
return 10;
}
9.類定義不完整,例如:
refimagedll.h(14) : error C2236: unexpected 'class' 'CRefImageListDll'
一般是因為在該文件包含的文件中存在類定義不完整,例如:
calss a{
int age;
}
后面少了一個分號,應該改成:
class a{
int age;
};
10.純虛類不能生成實例,例如:
d:/program files/microsoft visual studio/vc98/mfc/include/afxtempl.h(201) : error C2259: 'CKernel' : cannot instantiate abstract class due to following members:
如下:
class a{
public:
virtual void SetValue(int i)=NULL;
}
class b : public a{
private:
int m_iID;
public:
}
這樣的話,B 也不能實例化,因為在 B 中沒有實現 SetValue() 方法,在 B 中實現 SetValue() 方法即可解決。
11.重復釋放導致的問題
User breakpoint called from code at 0x77f9193c
以上原因是由於釋放了一個類的成員,最后在作該類的析構時由於它的成員已經被釋放導致出錯(該成員被釋放但是沒有設 NULL)
12.試圖執行系統不支持的操作
請檢查當前窗口模塊是否使用了其他不屬於它自己的資源
13.在 Dll 里調用對話框等資源的方法(如何在動態鏈接庫中顯示對話框) 2006.7.24
在動態鏈接庫的顯示對話框函數中加入下面這句代碼即可:
AFX_MANAGE_STATE(AfxGetStaticModuleState());
如果需要導出對話框的對象,在外面進行顯示,則可以重載 DoModal() 方法,在該方法中加入 AFX_MANAGE_STATE(AfxGetStaticModuleState());
14.動態鏈接庫和靜態鏈接庫混用的問題
症狀:使用 LoadLibrary() 加載一個動態鏈接庫時,返回 0 ,函數不成功,調用 GetLastError() 返回結果 126 ,MSDN 如是說:
126 The specified module could not be found. ERROR_MOD_NOT_FOUND
經研究發現,是因為該動態鏈接庫采用了靜態的方式調用了另一個鏈接庫(B),而另一個鏈接庫則又采用靜態的方式調用了另一個動態鏈接庫(C),但是 C 卻沒有拷貝到程序所在目錄,所以導致不能正常加載
15.宏定義導致系統出錯
連出三個錯誤:
ignored on left of 'unsigned char' when no variable is declared
error C2143: syntax error : missing ';' before 'constant'
error C2106: '=' : left operand must be l-value
代碼如下:
byte R=(byte)(AColor & 0xFF);
如果按照常理,應該不會有問題,但是由於一個函數庫里面對 R 有定義,所以 R 便不能當做變量使用
16.Debug 版本的 GetDocument() 函數可用,而 Release 版本則不能使用,提示函數沒有實現代碼
檢查 .h 文件中最后是否函數如下代碼:
#ifndef _DEBUG // debug version in LCDModelView.cpp
inline CXXXDoc* CXXXView::GetDocument()
{ return (CXXXDoc*)m_pDocument; }
#endif
原理:對於從來都沒有調用的函數,可以沒有其實現代碼,如果含有有一處調用則一定要有其實現代碼,微軟采用宏定義來區分 Release 和 Debug 版本。
17.VC 環境下不能使用 FindFile 進行文件搜索的問題(劉棟嫣發現,陸寬解決 2007.3.1)
在 VC 的集成開發環境下,點擊搜索文件按鈕,VC 崩潰
檢查注冊表鍵:HKEY_CURRENT_USER/Software/Microsoft/DevStudio/6.0/SearchOld/FIF_InFolders
發現其值為一個不存在的目錄,導致崩潰,解決辦法是清除該鍵值即可
18.函數的參數要記得使用(2007.3.28)
如:error C2220: warning treated as error - no object file generated
或:warning C4100: 'AParamCount' : unreferenced formal parameter
19.VC工程每次都重新編譯(2007.4.18 王鄭發現)
問題:VC工程每次點擊 F7,F5或Ctrl+F5時,都會全部編譯
解決:發現是系統的時間比工程的創建時間早,導致該問題發生
20.DLL 的導出方式(2007.6.1)
1.在 def 文件中導出,格式為:Function @n 例如:ShowName @1
2.直接在函數的聲明加上 _declspec(dllexport) 標識符
需要注意的是:第一種只能導出函數,不能導出類,而第二種即可導出函數也可導出類
第二種方法有個問題:只能提供給 VC 的程序進行靜態的調用,因為其導出的函數名加上了參數的信息,例如:“?ShowName@@YAXXZ”
解決的辦法是在其聲明的前面加上 extern "C" ,例如:extern "C" _declspec(dllexport) void ShowName()
綜上所述:第二種方法既能支持靜態調用又能支持動態調用,並且還能支持類的導出
示例見附件
21.修改系統默認的調試器(2007.6.29)
Win2000:
注冊表:HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/WinNT/CurrentVersion/AeDebug
"C:/Program Files/Visual Studio/Common/MSDev/Bin/msdev.exe" -p %ld -e %ld
22.動態庫中 CString 函數析構時出錯(2008.2.25)
問題描述:用 CString 作為參數傳遞,主程序采用 Debug 版本編譯,DLL 采用 Release 編譯
在 CString 析構時出錯
解決方法是把主程序和DLL都采用 Debug 或 Release 編譯
23.每次在 VC 環境下運行程序時都要求重新編譯(2008.2.28)
問題:不管是否已經全部編譯過,都有如下的提示:
One or more files are out of date or do not exist.
These files need to be built:
/COMPANY/其他項目/印刷項目/PrintMBW_Workspace/Execute/PrintMBW.exe
./Release/MyImageWnd.obj
<more files...>
Would you like to build them?
解決:原因是由於代碼文件有日期比當前日期還要晚,導致編譯器認為 obj 文件不是最新的,所以要求重新編譯,解決方法是把那些文件的修改日期改為當前日期即可。
24.類成員函數指針計算不准的問題(2008.5.30 陸寬發現)
typedef char (CMyClass::*MyFunc)();
MyFunc *pFuncList=new MyFunc[16];
這段代碼應該創建一個長度為16的MyFunc類型的類成員函數指針數組,實際長度為64字節。但是創建的結果,是生成了一個實際長度為16字節的數組。將類型char替換為void,實際長度變成0字節,替換為int,實際長度為64字節,替換為double,實際長度為128字節。也就是說,vc編譯器將返回值的長度誤當作函數指針的長度了。但是sizeof(MyFunc)確實等於4。
如果用普通函數指針類型,去掉類型中的CMyClass::,則一切正常。
我認為這是vc編譯器的一個嚴重bug。但是因為這樣的語法一般只有框架代碼中才會用到,在實際代碼中較少出現,所以該bug很難被發覺。
解決:
分配普通的int類型數組,將返回的數組強制轉換為MyFunc *類型即可。
MyFunc *pFuncList=(MyFunc *)new int[16];
不知道新版VC中是否已經解決了此bug。
25.類成員函數指針的大小問題(2008.6.19 陸寬發現)
class CTestParentClass{
public:
CTestParentClass(){}
virtual void Call()=NULL;
};
class CTestChildClass : public CTestParentClass, CString{
public:
CTestChildClass() {}
virtual void Call(){
void (CTestChildClass::*p)()=MyFunc;
TRACE("size=%d/n", sizeof(p));
}
};
調用一下Call函數看看,指針的長度是8字節。
轉載請注明出處