다음을 통해 공유


예외 처리에서 동작의 차이점

기본 개념에 관리 예외를 사용 하 여 관리 되는 응용 프로그램에서 예외 처리에 대해 설명 합니다.이 항목의 일부 제한 및 예외 처리의 표준 동작과 다른 차이점에 자세히 설명 합니다.자세한 내용은 _set_se_translator 함수.

이동 중에 Finally 블록

점프는 __의 네이티브 C/C++ 코드에서마지막 블록 구조적된 예외 처리 (SEH) 사용 하 여이 경고를 생성 하지만 허용 됩니다.아래 /clr, 외부로 점프는 마지막 차단 오류가 발생 합니다:

// clr_exception_handling_4.cpp
// compile with: /clr
int main() {
   try {}
   finally {
      return 0;   // also fails with goto, break, continue
    }
}   // C3276

예외 필터에서 예외 발생

처리 중 예외를 발생 시기는 예외 필터 관리 코드 내에서 예외를 catch 이며 0을 반환 하는 필터 처럼 취급 합니다.

어디 중첩 된 예외 발생, 네이티브 코드에서이 동작을 반대로 ExceptionRecord 필드에 EXCEPTION_RECORD 구조 (에서 반환 된 GetExceptionInformation) 설정 되어 및 ExceptionFlags 0x10 비트 필드를 설정 합니다.다음 예제에서는 동작의이 차이 보여 줍니다.

// clr_exception_handling_5.cpp
#include <windows.h>
#include <stdio.h>
#include <assert.h>

#ifndef false
#define false 0
#endif

int *p;

int filter(PEXCEPTION_POINTERS ExceptionPointers) {
   PEXCEPTION_RECORD ExceptionRecord = 
                     ExceptionPointers->ExceptionRecord;

   if ((ExceptionRecord->ExceptionFlags & 0x10) == 0) {
      // not a nested exception, throw one
      *p = 0; // throw another AV
   }
   else {
      printf("Caught a nested exception\n");
      return 1;
    }

   assert(false);

   return 0;
}

void f(void) {
   __try {
      *p = 0;   // throw an AV
   }
   __except(filter(GetExceptionInformation())) {
      printf_s("We should execute this handler if "
                 "compiled to native\n");
    }
}

int main() {
   __try {
      f();
   }
   __except(1) {
      printf_s("The handler in main caught the "
               "exception\n");
    }
}

2ww6y7y2.collapse_all(ko-kr,VS.110).gifOutput

Caught a nested exception
We should execute this handler if compiled to native

관련이 Rethrows

/clrrethrowing (관련이 rethrow로 알려진) catch 처리기 외부에서 예외를 지원 하지 않습니다.이 형식의 예외 처리 표준 C++ rethrow로.Rethrow 관련이 있을 때 현재 관리 되는 예외가 발생 하면 예외는 C++ 예외로 래핑된 이며 다음 다시 throw 합니다.형식의 예외로이 형식의 예외를 catch 있습니다만 System::SEHException.

다음 예제에서는 C++ 예외로 rethrow 되는 관리 되는 예외를 보여 줍니다.

// clr_exception_handling_6.cpp
// compile with: /clr
using namespace System;
#include <assert.h>
#include <stdio.h>

void rethrow( void ) {
   // This rethrow is a dissasociated rethrow.
   // The exception would be masked as SEHException.
   throw;
}

int main() {
   try {
      try {
         throw gcnew ApplicationException;
      }
      catch ( ApplicationException^ ) {
         rethrow();
         // If the call to rethrow() is replaced with
         // a throw statement within the catch handler,
         // the rethrow would be a managed rethrow and
         // the exception type would remain 
         // System::ApplicationException
      }
   }

    catch ( ApplicationException^ ) {
      assert( false );

      // This will not be executed since the exception
      // will be masked as SEHException.
    }
   catch ( Runtime::InteropServices::SEHException^ ) {
      printf_s("caught an SEH Exception\n" );
    }
}

2ww6y7y2.collapse_all(ko-kr,VS.110).gifOutput

caught an SEH Exception

예외 필터 및 발생할 수 있습니다

필터를 반환 하는 경우 EXCEPTION_CONTINUE_EXECUTION 필터를 반환 하는 경우에 관리 되는 응용 프로그램에서이 간주 됩니다 EXCEPTION_CONTINUE_SEARCH.이러한 상수에 대 한 자세한 내용은 시도-문을 제외 하 고.

다음 예제에서는 이러한 차이 보여 줍니다.

// clr_exception_handling_7.cpp
#include <windows.h>
#include <stdio.h>
#include <assert.h>

int main() {
   int Counter = 0;
   __try {
      __try  {
         Counter -= 1;
         RaiseException (0xe0000000|'seh',
                         0, 0, 0);
         Counter -= 2;
      }
      __except (Counter) {
         // Counter is negative,
         // indicating "CONTINUE EXECUTE"
         Counter -= 1;
      }
    }
    __except(1) {
      Counter -= 100;
   }

   printf_s("Counter=%d\n", Counter);
}

2ww6y7y2.collapse_all(ko-kr,VS.110).gifOutput

Counter=-3

_Set_se_translator 함수

번역기 기능을 설정 하는 호출에 의해 _set_se_translator을 처리 하므로 관리 되지 않는 코드에만 영향을 줍니다.다음 예제에서는 이러한 제한을 보여 줍니다.

// clr_exception_handling_8.cpp
// compile with: /clr /EHa
#include <iostream>
#include <windows.h>
#include <eh.h>
#pragma warning (disable: 4101)
using namespace std;
using namespace System;

#define MYEXCEPTION_CODE 0xe0000101

class CMyException {
public:
   unsigned int m_ErrorCode;
   EXCEPTION_POINTERS * m_pExp;

   CMyException() : m_ErrorCode( 0 ), m_pExp( NULL ) {}

   CMyException( unsigned int i, EXCEPTION_POINTERS * pExp )
         : m_ErrorCode( i ), m_pExp( pExp ) {}

   CMyException( CMyException& c ) : m_ErrorCode( c.m_ErrorCode ),
                                      m_pExp( c.m_pExp ) {}

   friend ostream& operator << 
                 ( ostream& out, const CMyException& inst ) {
      return out <<  "CMyException[\n" <<  
             "Error Code: " << inst.m_ErrorCode <<  "]";
    }
};

#pragma unmanaged 
void my_trans_func( unsigned int u, PEXCEPTION_POINTERS pExp ) {
   cout <<  "In my_trans_func.\n";
   throw CMyException( u, pExp );
}

#pragma managed 
void managed_func() {
   try  {
      RaiseException( MYEXCEPTION_CODE, 0, 0, 0 );
   }
   catch ( CMyException x ) {}
   catch ( ... ) {
      printf_s("This is invoked since "
               "_set_se_translator is not "
               "supported when /clr is used\n" );
    }
}

#pragma unmanaged 
void unmanaged_func() {
   try  {
      RaiseException( MYEXCEPTION_CODE, 
                      0, 0, 0 );
   }
   catch ( CMyException x ) {
      printf("Caught an SEH exception with "
             "exception code: %x\n", x.m_ErrorCode );
    }
    catch ( ... ) {}
}

// #pragma managed 
int main( int argc, char ** argv ) {
   _set_se_translator( my_trans_func );

   // It does not matter whether the translator function
   // is registered in managed or unmanaged code
   managed_func();
   unmanaged_func();
}

2ww6y7y2.collapse_all(ko-kr,VS.110).gifOutput

This is invoked since _set_se_translator is not supported when /clr is used
In my_trans_func.
Caught an SEH exception with exception code: e0000101

참고 항목

참조

safe_cast(C++ 구성 요소 확장)

Visual C++에서는 처리 된 예외

기타 리소스

예외 처리(C++ 구성 요소 확장)