转载:_set_se_translator 用法 + C++异常与windows异常

原创 2007年09月27日 16:09:00

使用c++异常时,包含对象编译不过,百思不解。补一补关于异常的知识
 
代码:
void func( )
{
        CString strTest;         // 错误!结构化异常无法解析C++ 对象
        __try{
           ...
        }
        __except(...){
                     ...
         }
}
编译信息:
warning C4509: nonstandard extension used: 'func' uses SEH and 'CString' has destructor
error C2712: Cannot use __try in functions that require object unwinding
 
这确实很令人费解,明明程序很简单的吗?而且程序中只用到了 SEH 异常模型的 try-except 语法,甚至 SEH 与 C++ 异常模型两者混合使用的情况都不存在。那么编译出错的原因究竟何在呢?
 
那原因就是: 同样还是由于在一个函数不能采用两种形式的异常处理机制而导致的编译错误。这岂不是更迷惑了。其实不然,这是因为: 在 C++ 异常处理模型中,为了能够在异常发生后,保证正确地释放相关的局部变量(也即调用析构函数),它必须要跟踪每一个“对象”的创建过程,这种由于异常产生而导致的对象析构的过程,被称为“ unwind ”。因此,如果一个函数中有局部对象的存在,那么它就一定会存在 C++ 的异常处理机制(也即会给此函数插入一些用于 C++ 异常处理“代码和信息”),这样,如果该函数中在再使用 try-except 机制,岂不是就冲突了吗?所以编译器也就报错了,因为它处理不了了。
 
附:
关于异常的文章
http://51cmm.csai.cn/ExpertEyes/No136.htm
...
http://51cmm.csai.cn/ExpertEyes/No167.htm
 
C++异常笔记
 ===================================================
C++异常和Windows结构异常的比较
Windows结构异常有如下几个特性:
1、它使用__try、__except、__finally和__leave关键字和RaiseException API;
2、它由Windows所支持,因此它不适合其它操作系统
3、它不处理C++对象的解析
说明:在使用Windows结构异常的函数内,如果有C++对象,编译器会发
出:error C2712: Cannot use __try in functions that require object unwinding 的错误。
如:
void fun( )
{
        CObject       object ;         // 错误!结构化异常无法解析C++ 对象
        __try{
           ...
        }
        __except(...){
                     ...
              }
}
4、它用为硬件异常(例如访问非法或被零除)或操作系统异常的结果被抛出。
       也可以作为RaiseException函数的结果被抛出;
 
而C++异常的特点是:
1、使用try、throw和catch等关键字;
2、它处理C++对象的解析;
3、它作为throw语句的结果被抛出;
 
注:MFC提供了第三种异常处理机制。它使用几个异常处理宏,这些宏现在也被编译成C++异常,因此没有必要在新的代码中使用它们!在MFC编程中,异
常对象都是从CExcept派生。大多数MFC异常处理对象都是动态分配的,因此当它们被捕获时,必须被删除;而没有捕获的MFC异常由MFC本身在AfxCa-
llWndProc函数中捕获并删除。
因为C++异常不能处理硬件和操作系统异常,因此需要将结构异常转化为
C++异常。
 
如何将结构异常转化为C++异常
Visual C++ 允许你通过使用_set_se_translator函数将结构异常转化为C++异常。
 
#include <eh.h>
class CSEHException
{
       public :
       CSEHException( UINT code , PEXCEPTION_POINTERS pep )
{
       m_exceptionCode      = code ;
       m_exceptionRecord   = *pep->ExceptionRecord ;
       m_context               = *pep->ContextRecord ;
       ASSERTE( m_exceptionCode == m_exceptionRecord.ExceptionCode );
}
operator unsigned int() { return m_exceptionCode ; }
 
UINT m_exceptionCode ;
EXCEPTION_RECORD   m_exceptionRecord ;
CONTEXT   m_context ;
} ;
 
// 结构化异常到C++异常转化器
void cdecl TranslateSEHtoCE( UINT code , PEXCEPTIONPOINTERS pep )
{
throw CSEHException( code , pep ) ;
}
 
int APIENTRY  WinMain( ……)
{
// 安装异常转化器
setse_translator( TranslateSEHtoCE ) ;
}
 
注意,异常转化器在每个线程的基础上进行工作,因此你需要为每一个线程安装一个转化器。这种异常转化器有一个副作用,你会在输出窗口的Debug标签中看见两个异常跟踪消息:一个是为了原来的结构异常,另一个是为了转化后的C++异常。使用了异常转化器后,你就可以像捕获C++异常一样捕获结构异常。

_set_se_translator 用法 + C++异常与windows异常

使用c++异常时,包含对象编译不过,百思不解。补一补关于异常的知识   代码: void func( ) {         CString strTest;         // 错误!结...
  • changyang208
  • changyang208
  • 2013年08月22日 17:19
  • 559

set_se_translator 用法 + C++异常与windows异常

使用c++异常时,包含对象编译不过,百思不解。补一补关于异常的知识 代码: void func( ) { CString strTest; // 错误!结构化异常无法解析C++ 对象 __t...
  • TXH0001
  • TXH0001
  • 2012年10月17日 16:35
  • 515

_set_se_translator 用法 与C++异常与windows结构化异常SEH

使用c++异常时,包含对象编译不过,百思不解。补一补关于异常的知识   代码: void func( ) {         CString strTest;         // 错误!结...
  • ztsinghua
  • ztsinghua
  • 2014年08月12日 11:36
  • 609

采用Win32结构化异常(SEH)捕捉所有未捕捉的异常[C++]

代码 #include "stdafx.h" #include #include using namespace std; int _tmain(int argc, _TCHAR* argv[]...
  • cocoasprite
  • cocoasprite
  • 2014年09月15日 10:34
  • 1667

C++异常及错误处理

计算机应用程序中离不开错误处理,尤其是生产型大型软件系统。应用软件系统运行属于循环处理事务,出错后需要保证不能让软件程序直接退出。这就需要使用一定的程序容错处理来应对。一般情况下,大型软件开发中的软件...
  • u010982858
  • u010982858
  • 2015年01月08日 23:26
  • 1007

Windows 结构化异常与 C / C++异常的一些事

一直以来对“异常”以及相关的知识很模糊,这次做个整理,回答几个基本问题以帮助对“异常”的理解: C语言的异常C语言版的try/catch: setjmp, longjmp C++的异常(try/c...
  • vincentccnt
  • vincentccnt
  • 2015年01月20日 16:56
  • 1529

C++异常与继承

在C++程序中,表示异常的类通常被组成为一个组(即如在前面各节讨论的那样)或者一个层次结构。 ◆ 1、例如:定义一个称为Excp的基类,由它来打印错误信息: class Excp { publ...
  • zk65645
  • zk65645
  • 2017年02月07日 19:48
  • 410

C++异常rethrow【转】

转自 http://se.csai.cn/ExpertEyes/200801031114531905.htm 在相遇篇中的《第5集 C++的异常rethrow》文章中,已经比较详细...
  • fall221
  • fall221
  • 2013年06月24日 22:01
  • 1817

c++异常追踪

C++语言的运行时环境是基于栈的环境,堆栈跟踪(trace stack)就是程序运行时能够跟踪并打印所调用的函数、变量及返回地址等,C++异常中的堆栈跟踪就是当程序抛出异常时,能够把导致抛出异常的语句...
  • u012964993
  • u012964993
  • 2014年04月29日 11:40
  • 950

细说windows的异常处理和实现——结构化异常

C++里面有使用异常处理的机制,但是那些需要throw catch捕捉等操作 而通常一个win程序,我们会因为各种原因导致其crash,而不一定是throw 了某个exception。我们需要这样...
  • leonwei
  • leonwei
  • 2013年04月27日 01:53
  • 2208
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:转载:_set_se_translator 用法 + C++异常与windows异常
举报原因:
原因补充:

(最多只允许输入30个字)