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

摘要:
$ CArray@VCCameraRefImage@@V1@@@H@Z)已在InterFaceFile中定义。obj h文件定义了一个函数并完全实现了它。因此,当它包含在多个文件中时,会出现重复的定义错误。解决方案是将函数定义为内联,这样它就不再是一个函数,而是直接被一段代码替换,例如:inlineGetAge(){return10;}9.不完整的类定义,例如:refimagedll h:ErrorC2236:意外的“class”“CRefImageListDll”通常是由于文件中包含的文件中的类定义不完整,例如calssa{intage;}缺少分号。应将其更改为:classa{intage;};10.纯虚拟类无法生成实例,例如:d:/programfiles/microsoft visual studio/vc98/mfc/include/afxtempl h:ErrorC2259:“CKernel”:无法实例化抽象类,原因如下:classa{public:virtualvoid SetValue=NULL;}Classb:public{private:intm_iID;public:}在这种情况下,B不能被实例化,因为SetValue()方法没有在B中实现,它可以通过在B中执行SetValue方法来解决。

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字节。

转载请注明出处

免责声明:文章转载自《我的 VC++ 常见错误问题解决办法》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Jquery Math ceil()、floor()、round()比较与用法shiro细节、默认的过滤器、匹配模式和顺序下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

制作C/C++动态链接库(dll)若干注意事项

一、CC++ 运行时库编译选项简单说明 问题:我的dll别人没法用 运行时库是个很复杂的东西,作为开发过程中dll制作需要了解的一部分,这里主要简单介绍一下如何选择编译选项。 在我们的开发过程中时常会遇到这样的问题: 1. 我的VS版本比较高(比如:VS2012),我想制作一个dll,封装了几个函数给别人用。 2. 打包后发现我的dll引用了msvcr1...

ecshop 二次开发 函数列表大全

最近进行ecshop的二次开发,整理了一部分的函数,另外在ecshop论坛上面也发现了很多函数说明,整理汇总如下,供大家参考。 所有函数功能说明: lib_time.phpgmtime() P: 获得当前格林威治时间的时间戳 /$0server_timezone() P: 获得服务器的时区 /$0local_mktime($hour = NULL , $mi...

Chromium base 基础库概览

Chromium 基础库概览 Chromium 基础库包括的内容十分繁杂,我把其中的主要部分大致分为以下几类: 1. 容器类型Chromium 的代码主要使用 STL 容器类型,比如 std::vector,std::list,另外 GCC 和 MSVC 提供的 STL 扩展容器类型 hash_map 和 hash_set 也在 Chromium 中使用...

linux系统下信号具体解释2

信号是UNIX 系统所使用的进程通信方法中,最古老的一种。信号不但能从内核发往一个进程,也能从一个进程发往还有一个进程。比如,用户在后台启动了一个要运行较长时间的程序,假设想中断其运行,能够用kill 命令把SIGTERM信号发送给这个进程,SIGTERM 将终止此进程的运行。信号还提供了向UNIX 系统进程传送软中断的简单方法。信号能够中断一个进程,而...

bind函数的作用

  面向连接的网络应用程序分为客户端和服务器端。服务器端的执行流程一般为4步,客户端程序相对简单,一般需要两个步骤。 服务器端执行流程4步如下: (1)调用socket函数,建立一个套接字,该套接字用于接下来的网络通信。 (2)调用bind函数,将该套接字绑定到一个地址,并制定一个端口号, (3)调用listen函数,使用该套接字监听连接请求 (4)当请求...

网络编程,从socket到epoll

网络编程,从socket到epoll 参考链接:https://www.bilibili.com/video/BV11Z4y157RY?p=2&spm_id_from=pageDriver socket基本知识: socket分类: socekt提供了流和数据报两种通信机制,即流socket和数据报socket。 简单的socket通信流程: 先...