您的位置:首页 > 编程语言 > C语言/C++

我的 VC++ 常见错误问题解决办法

2016-06-02 16:31 507 查看
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字节。
 
 
转载请注明出处

分类: C++/C

  博客地址:http://www.cnblogs.com/lidabo/archive/2012/12/30/2839770.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: