MFC中程序没有错但为什么运行不了

MFC中程序没有错但为什么运行不了,第1张

哪些情况下 Release 版会出错

有了上面的介绍,我们再来逐个对照这些选项看看 Release 版错误是怎样产生的

1 Runtime Library:链接哪种运行时刻函数库通常只对程序的性能产生影响。调试版本的 Runtime Library 包含了调试信息,并采用了一些保护机制以帮助发现错误,因此性能不如发布版本。编译器提供的 Runtime Library 通常很稳定,不会造成 Release 版错误;倒是由于 Debug 的 Runtime Library 加强了对错误的检测,如堆内存分配,有时会出现 Debug 有错但 Release 正常的现象。应当指出的是,如果 Debug 有错,即使 Release 正常,程序肯定是有 Bug 的,只不过可能是 Release 版的某次运行没有表现出来而已。

2 优化:这是造成错误的主要原因,因为关闭优化时源程序基本上是直接翻译的,而打开优化后编译器会作出一系列假设。这类错误主要有以下几种:

(1) 帧指针(Frame Pointer)省略(简称 FPO ):在函数调用过程中,所有调用信息(返回地址、参数)以及自动变量都是放在栈中的。若函数的声明与实现不同(参数、返回值、调用方式),就会产生错误 ————但 Debug 方式下,栈的访问通过 EBP 寄存器保存的地址实现,如果没有发生数组越界之类的错误(或是越界“不多”),函数通常能正常执行;Release 方式下,优化会省略 EBP 栈基址指针,这样通过一个全局指针访问栈就会造成返回地址错误是程序崩溃。C++ 的强类型特性能检查出大多数这样的错误,但如果用了强制类型转换,就不行了。你可以在 Release 版本中强制加入 /Oy- 编译选项来关掉帧指针省略,以确定是否此类错误。此类错误通常有:

● MFC 消息响应函数书写错误。正确的应为

afx_msg LRESULT OnMessageOwn(WPARAM wparam, LPARAM lparam);

ON_MESSAGE 宏包含强制类型转换。防止这种错误的方法之一是重定义 ON_MESSAGE 宏,把下列代码加到 stdafxh 中(在#include "afxwinh"之后),函数原形错误时编译会报错

#undef ON_MESSAGE

#define ON_MESSAGE(message, memberFxn) \

{ message, 0, 0, 0, AfxSig_lwl, \

(AFX_PMSG)(AFX_PMSGW)(static_cast< LRESULT (AFX_MSG_CALL \

CWnd::)(WPARAM, LPARAM) > (&memberFxn) },

(2) volatile 型变量:volatile 告诉编译器该变量可能被程序之外的未知方式修改(如系统、其他进程和线程)。优化程序为了使程序性能提高,常把一些变量放在寄存器中(类似于 register 关键字),而其他进程只能对该变量所在的内存进行修改,而寄存器中的值没变。如果你的程序是多线程的,或者你发现某个变量的值与预期的不符而你确信已正确 的设置了,则很可能遇到这样的问题。这种错误有时会表现为程序在最快优化出错而最小优化正常。把你认为可疑的变量加上 volatile 试试。

(3) 变量优化:优化程序会根据变量的使用情况优化变量。例如,函数中有一个未被使用的变量,在 Debug 版中它有可能掩盖一个数组越界,而在 Release 版中,这个变量很可能被优化调,此时数组越界会破坏栈中有用的数据。当然,实际的情况会比这复杂得多。与此有关的错误有:

● 非法访问,包括数组越界、指针错误等。例如

void fn(void)

{

int i;

i = 1;

int a[4];

{

int j;

j = 1;

}

a[-1] = 1;//当然错误不会这么明显,例如下标是变量

a[4] = 1;

}

j 虽然在数组越界时已出了作用域,但其空间并未收回,因而 i 和 j 就会掩盖越界。而 Release 版由于 i、j 并未其很大作用可能会被优化掉,从而使栈被破坏。

3 _DEBUG 与 NDEBUG :当定义了 _DEBUG 时,assert() 函数会被编译,而 NDEBUG 时不被编译。除此之外,VC++中还有一系列断言宏。这包括:

ANSI C 断言 void assert(int expression );

C Runtime Lib 断言 _ASSERT( booleanExpression );

_ASSERTE( booleanExpression );

MFC 断言 ASSERT( booleanExpression );

VERIFY( booleanExpression );

ASSERT_VALID( pObject );

ASSERT_KINDOF( classname, pobject );

ATL 断言 ATLASSERT( booleanExpression );

此外,TRACE() 宏的编译也受 _DEBUG 控制。

所有这些断言都只在 Debug版中才被编译,而在 Release 版中被忽略。唯一的例外是 VERIFY() 。事实上,这些宏都是调用了 assert() 函数,只不过附加了一些与库有关的调试代码。如果你在这些宏中加入了任何程序代码,而不只是布尔表达式(例如赋值、能改变变量值的函数调用 等),那么 Release 版都不会执行这些 *** 作,从而造成错误。初学者很容易犯这类错误,查找的方法也很简单,因为这些宏都已在上面列出,只要利用 VC++ 的 Find in Files 功能在工程所有文件中找到用这些宏的地方再一一检查即可。另外,有些高手可能还会加入 #ifdef _DEBUG 之类的条件编译,也要注意一下。

顺便值得一提的是 VERIFY() 宏,这个宏允许你将程序代码放在布尔表达式里。这个宏通常用来检查 Windows API 的返回值。有些人可能为这个原因而滥用 VERIFY() ,事实上这是危险的,因为 VERIFY() 违反了断言的思想,不能使程序代码和调试代码完全分离,最终可能会带来很多麻烦。因此,专家们建议尽量少用这个宏。

4 /GZ 选项:这个选项会做以下这些事

(1) 初始化内存和变量。包括用 0xCC 初始化所有自动变量,0xCD ( Cleared Data ) 初始化堆中分配的内存(即动态分配的内存,例如 new ),0xDD ( Dead Data ) 填充已被释放的堆内存(例如 delete ),0xFD( deFencde Data ) 初始化受保护的内存(debug 版在动态分配内存的前后加入保护内存以防止越界访问),其中括号中的词是微软建议的助记词。这样做的好处是这些值都很大,作为指针是不可能的(而且 32 位系统中指针很少是奇数值,在有些系统中奇数的指针会产生运行时错误),作为数值也很少遇到,而且这些值也很容易辨认,因此这很有利于在 Debug 版中发现 Release 版才会遇到的错误。要特别注意的是,很多人认为编译器会用 0 来初始化变量,这是错误的(而且这样很不利于查找错误)。

(2) 通过函数指针调用函数时,会通过检查栈指针验证函数调用的匹配性。(防止原形不匹配)

(3) 函数返回前检查栈指针,确认未被修改。(防止越界访问和原形不匹配,与第二项合在一起可大致模拟帧指针省略 FPO )

通常 /GZ 选项会造成 Debug 版出错而 Release 版正常的现象,因为 Release 版中未初始化的变量是随机的,这有可能使指针指向一个有效地址而掩盖了非法访问。

除此之外,/Gm /GF 等选项造成错误的情况比较少,而且他们的效果显而易见,比较容易发现。

--------------------------------------------------------------

Release是发行版本,比Debug版本有一些优化,文件比Debug文件小

Debug是调试版本,包括的程序信息更多

Release方法:

build->batch build->build就OK

具体可以看看下面的链接

在用VS2015调试一个基于对话框工程时,当运行到CDialogEx::OnInitDialog()方法的时候,d出提示窗口“ 不支持尝试执行的 *** 作 ”。

在控件关联函数 DoDataExchange() 中查找并删除对应的控件变量 / 删除那些多余的变量。

这样,当再次运行此程序时,便不会在出现“不支持尝试执行的 *** 作”这个问题。

Bug无处不在,需要我们静下心,通过百度或google,最终解决掉这个Bug。

哪有什么天下无Bug,只是有人在替你负重前行。 加油!

vc6下MFC通过点击菜单项d出对话框: 1、新建MFC工程,在资源中新建一个对话框,右击建立类向导,为对话框新建一个类 2、在view类中建立点击菜单项的响应函数 3、在响应函数中建立对话框的对象,调用DoModal函数d出对话框 view类cpp中要include对话框类的头文件 不会的话,联系我qq:342135961,我发给你代码 建议你看孙鑫的MFC视频,入手很快

MFC是微软的VC++带的视窗用的基本库。

MFC编程就是调用这个基本库,写出类似于IE浏览器这种程序,就是用鼠标,键盘为工具的人机会话式的程序。

学MFC的要点是会用visual Studio 建程序框架,用VC++语言添加程序内容,编译和运行。关键要会VC++。

LL

mfc71ddll

MFCO42DDLL

MSVCP60DDLL

msvcrtddll

把它们放到用户c:/windows/system32/文件中就可以运行你的mfc程序了

(这些文件在装有C++的机器中c:/windows/system32/目录下都有)

没有啊,不会哦,我当时是C++

60。

你现在就用你能找到的的几个dll,把它们放到其它没有装C++的电脑中,运行你的mfc,看看还缺少什么dll,再根据情况添加吧

Visual C++包含MFC应用程序向导,可用于兼容MFC的应用程序。在ATL程序中也可以手动添加MFC支持。在向导中有各种选项以定制生成的程序的功能,例如界面风格、语种、数据库开发支持、打印支持、自动化支持、ActiveX支持、网络支持、基于HTML的帮助文档支持等等

MFC,微软基础类(Microsoft Foundation Classes),同VCL类似,是一种Application Framework,随微软Visual C++ 开发工具发布。目前最新版本为90(截止2008年11月)。该类库提供一组通用的可重用的类库供开发人员使用。大部分类均从CObject 直接或间接派生,只有少部分类例外。

MFC 应用程序的总体结构通常由 由开发人员从MFC类派生的几个类和一个CWinApp类对象(应用程序对象)组成。MFC 提供了MFC AppWizard 自动生成框架。

Windows 应用程序中,MFC 的主包含文件为"Afxwinh"。

此外MFC的部分类为MFC/ATL 通用,可以在Win32 应用程序中单独包含并使用这些类。

由于它的易用性,初学者常误认为VC++开发必须使用MFC。这种想法是错误的。作为Application Framework,MFC的使用只能提高某些情况下的开发效率,只起到辅助作用,而不能替代整个Win32 程序设计。

MFC,微软基础类(Microsoft Foundation Classes),实际上是微软提供的,用于在C++环境下编写应用程序的一个框架和引擎,VC++是WinDOS下开发人员使用的专业C++ SDK(SDK,Standard SoftWare Develop Kit,专业软件开发平台),MFC就是挂在它之上的一个辅助软件开发包,MFC作为与VC++血肉相连的部分(注意C++和VC++的区别:C++是一种程序设计语言,是一种大家都承认的软件编制的通用规范,而VC++只是一个编译器,或者说是一种编译器+源程序编辑器的IDE,WS,PlatForm,这跟Pascal和Delphi的关系一个道理,Pascal是Delphi的语言基础,Delphi使用Pascal规范来进行Win下应用程序的开发和编译,却不同于Basic语言和VB的关系,Basic语言在VB开发出来被应用的年代已经成了Basic语言的新规范,VB新加的Basic语言要素,如面向对象程序设计的要素,是一种性质上的飞跃,使VB既是一个IDE,又成长成一个新的程序设计语言),MFC同BC++集成的VCL一样是一个非外挂式的软件包,类库,只不过MFC类是微软为VC++专配的

MFC是Win API与C++的结合,API,即微软提供的WinDOS下应用程序的编程语言接口,是一种软件编程的规范,但不是一种程序开发语言本身,可以允许用户使用各种各样的第三方(如我是一方,微软是一方,Borland就是第三方)的编程语言来进行对WinDOS下应用程序的开发,使这些被开发出来的应用程序能在WinDOS下运行,比如VB,VC++,Java,Dehpi编程语言函数本质上全部源于API,因此用它们开发出来的应用程序都能工作在WinOS的消息机制和绘图里,遵守WinDOS作为一个 *** 作系统的内部实现,这其实也是一种必要,微软如果不提供API,这个世上对Win编程的工作就不会存在,微软的产品就会迅速从时尚变成垃圾,上面说到MFC是微软对API函数的专用C++封装,这种结合一方面让用户使用微软的专业C++ SDK来进行Win下应用程序的开发变得容易,因为MFC是对API的封装,微软做了大量的工作,隐藏了好多程序开发人员在Win下用C++ & MFC编制软件时的大量内节,如应用程序实现消息的处理,设备环境绘图,这种结合是以方便为目的的,必定要付出一定代价(这是微软的一向作风),因此就造成了MFC对类封装中的一定程度的的冗余和迂回,但这是可以接受的

最后要明白MFC不只是一个功能单纯的界面开发系统,它提供的类绝大部分用来进行界面开发,关联一个窗口的动作,但它提供的类中有好多类不与一个窗口关联,即类的作用不是一个界面类,不实现对一个窗口对象的控制(如创建,销毁),而是一些在WinDOS(用MFC编写的程序绝大部分都在WinDOS中运行)中实现内部处理的类,如数据库的管理类等,学习中最应花费时间的是消息和设备环境,对C++和MFC的学习中最难的部分是指针,C++面向对像程序设计的其它部分,如数据类型,流程控制都不难,建议学习数据结构C++版。

MFC是微软封装了的API。什么意思呢?windows作为一个提供功能强大的应用程序接口编程的 *** 作系统,的确方便了许多程序员,传统的win32开发(直接使用windows的接口函数API)对于程序员来说非常的困难,因为,API函数实在太多了,而且名称很乱,从零构架一个窗口动辄就是上百行的代码。MFC是面向对象程序设计与Application framework的完美结合,他将传统的API进行了分类封装,并且为你创建了程序的一般框架,

[编辑本段]历史

MFC是在1992年的Microsoft 16位版的C/C++编译器的70版本中作为一个扩展轻量级的Windows API面向对象的C++封装库而引入的。此时,C++因为它在和API方面的卓越表现,刚刚开始被用来取代C应用于开发商用软件。因此,他们推出了替代早期的老式的字符界面的集成开发环境(IDE)的PWB。

有趣的是,MFC使用“Afx”作为所有的函数,宏及标准预编译头文件名的前缀。因为在MFC的早期开发阶段它叫“Application Framework Extensions”缩写为“Afx”。MFC这个名字被采用得太晚了以至于没来得及修改这些引用。

最近,MFC80和Visual Studio 2005一起发布了;MFC90和Visual Studio 2008一起发布。在免费的Express版本的Visual Studio 2005/2008中没有包含MFC。

作为一个强有力的竞争对手,为Borland的Turbo C++编译器设计OWL(Object Windows Library)在同一时间也发布了。但最后,Borland停止了对OWL的继续开发并且不久就从Microsoft那里购买了MFC头文件,动态链接库等的授权,微软没有提供完整的MFC的集成支持。之后Borland发布了VCL(Visual Component Library)来替换OWL框架。

[编辑本段]版本更新

新产品版本 MFC版本

Microsoft C/C++ 70 MFC 10

Visual C++ 10 MFC 20

Visual C++ 15 MFC 25

Visual C++ 20 MFC 30

Visual C++ 21 MFC 31

Visual C++ 22 MFC 32

Visual C++ 40 MFC 40 (mfc40dll included with Windows 95)

Visual C++ 41 MFC 41

Visual C++ 42 MFC 42 (mfc42dll included with the Windows 98 original release)

eMbedded Visual C++ 30 MFC 42 (mfc42dll)

Visual C++ 50 MFC 421 (mfc42dll)

Visual C++ 60 MFC 60 (mfc42dll)

eMbedded Visual C++ 40 none

Visual C++ NET 2002 MFC 70 (mfc70dll)

Visual C++ NET 2003 MFC 71 (mfc71dll)

Visual C++ 2005 MFC 80 (mfc80dll)

Visual C++ 2008 MFC 9021022 (mfc90dll)

Visual C++ 2008 with Feature Pack MFC 9030411 (mfc90dll)

MFC为Mass Flow Controller的缩写,即质量流量控制。流体在旋转的管内流动时会对管壁产生一个力,它是科里奥利在1832年研究水轮机时发现的,简称科氏力。质量流量计以科氏力为基础,在传感器内部有两根平行的T型振管,中部装有驱动线圈,两端装有拾振线圈,变送器提供的激励电压加到驱动线圈上时,振动管作往复周期振动,工业过程的流体介质流经传感器的振动管,就会在振管上产生科氏力效应,使两根振管扭转振动,安装在振管两端的拾振线圈将产生相位不同的两组信号,这两个信号差与流经传感器的流体质量流量成比例关系。计算机解算出流经振管的质量流量。不同的介质流经传感器时,振管的主振频率不同,据此解算出介质密度。安装在传感器器振管上的铂电阻可间接测量介质的温度。

质量流量计直接测量通过流量计的介质的质量流量,还可测量介质的密度及间接测量介质的温度。由于变送器是以单片机为核心的智能仪表,因此可根据上述三个基本量而导出十几种参数供用户使用。质量流量计组态灵活,功能强大,性能价格比高,是新一代流量仪表。

测量管道内质量流量的流量测量仪表。在被测流体处于压力、温度等参数变化很大的条件下,若仅测量体积流量,则会因为流体密度的变化带来很大的测量误差。在容积式和差压式流量计中,被测流体的密度可能变化30%,这会使流量产生30~40%的误差。随着自动化水平的提高,许多生产过程都对流量测量提出了新的要求。化学反应过程是受原料的质量(而不是体积)控制的。蒸气、空气流的加热、冷却效应也是与质量流量成比例的。产品质量的严格控制、精确的成本核算、飞机和导d的燃料量控制,也都需要精确的质量流量测量。因此质量流量计是一种重要的流量测量仪表。

质量流量计可分为两类:一类是直接式,即直接输出质量流量;另一类为间接式或推导式,如应用超声流量计和密度计组合,对它们的输出再进行乘法运算以得出质量流量。

直接式质量流量计 直接式质量流量计有多种类型,如量热式、角动量式、陀螺式和双叶轮式等。

(1) 主要参数:

质量流量精度: ±0002×流量±零点漂移

密度测量精度: ±0003g/cm3

密度测量范围: 05~15g/cm3

温度测量范围: ±1°C

(2) 传感器相关数据:

环境温度: -40~60°C

介质温度: -50~200°C

防爆类型: iBⅡBT3

关联设备: 配套变送器

(3) 变送器相关数据:

工作温度: 0~60°C

相对湿度: 95%以下

电 源: 220±10%VAC,50Hz或24±5%VDC,40W

第三个参数需要一个LPCTSTR类型而不是CString类型,自己看看API它们的差别,还有不少类似的如:LPCSTR,string,LPSTR等等,都是可以转化的,自己去多了解一点,对你没坏处。(其实我是不记得了)

以上就是关于MFC中程序没有错但为什么运行不了全部的内容,包括:MFC中程序没有错但为什么运行不了、MFC | 程序运行出现问题“不支持尝试执行的 *** 作”、怎样用MFC编写一个对话框程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zz/9290280.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-26
下一篇2023-04-26

发表评论

登录后才能评论

评论列表(0条)

    保存