Exception Handling

Snoops

   

 
Migrating to .NET: A Pragmatic Path to Visual Basic .NET, Visual C++ .NET, and ASP.NET
By Dhananjay  Katre, Prashant  Halari, Narayana  Rao  Surapaneni, Manu  Gupta, Meghana  Deshpande

Table of Contents
Chapter 9.   Migrating to Visual C++ .NET


In this section, you will be introduced to the concept of exception handling mechanism in managed extensions and the ways in which the managed code handles unmanaged exceptions and vice versa. When an exception condition arises, program control is transferred to a block of code that can handle that exception, thus preventing abnormal termination of the application. If, however, no handler exists, the program is aborted. In other words, the exception handling allows for a graceful exit. Hence, it should be ensured that any exception that is raised is caught whether it is generated from the unmanaged or managed code. Native exception handling has been extended in the managed extensions to handle managed exceptions. We will refer to exceptions thrown by a managed type as a managed exception through out this chapter. The following are features of a managed exception:

  • A managed object can be thrown directly.

  • A value type object must be boxed before throwing the exception.

  • An unmanaged exception is automatically wrapped by System:: Runtime::InteropServices::SEHException(Structured Exception Handling) when thrown within managed code.

  • System::Exception is the recommended base class for all user -defined managed exception classes because it provides many useful methods for processing managed exceptions.

Exception Handling in Managed Extensions

Let us consider exception handling in managed extensions to get an understanding of the basic concepts before going into further details. In this section, we will deal with the mixing of managed and unmanaged code from the perspective of exception handling. Exception handling in managed extensions can be divided into the following categories:

  • Throwing exceptions in managed code using managed extensions

  • Handling exceptions in managed code using managed extensions

  • The role played by the __finally keyword

  • Handling exceptions thrown by the unmanaged code

Throwing Exceptions in Managed Code Using Managed Extensions

A pointer to any managed type class (i.e., __gc type) can be thrown as an exception by managed code. However, __value -type exception objects must be boxed before they can be thrown. The __value -type exception is illustrated in the following sample code. It is in the directory ValuetypeExceptions .

 graphics/icon01.gif //Declare a value class  __value class ValueException{  private:      String* m_Description;  public:      __property String* get_Description(){            return m_Description;      }      __property void set_Description(String* f_Description){            m_Description = f_Description;      }  };  void main(){      ValueException objValException;      throw __box(objValException);  } 

The __gc type exception is illustrated in the following code, which is in the directory GCtypeExceptions :

 graphics/icon01.gif //Exception thrown by __gc class  //Declare a gc class  __gc class GCException {  private:      String* m_Description;  public:      __property String* get_Description(){            return m_Description;      }      __property void set_Description(String* f_Description){            m_Description = f_Description;      }  };  void main(){      GCException *pGCException = new GCException;      throw pGCException;  } 

Try and Catch Blocks in Managed Extensions

Both managed and unmanaged exceptions can be caught using the same try and catch blocks. In the following example an unmanaged class UnmanagedException and a managed __gc class GCException have been declared. The exceptions of both the managed and unmanaged classes are being thrown by the same try block. However, different catch blocks handle the exceptions for the managed and unmanaged class separately. Thus we can also say that managed extensions support multiple catch blocks for a try block. This code is in the directory TryCatchblock_managed .

 graphics/icon01.gif //Declare an unmanaged class  class     UnmanagedException{  private:      char* m_Description;  public:      char* GetDescription(){  return m_Description;  }      void SetDescription(char* f_Description){  m_Description = (char *)  malloc(strlen(f_Description)*sizeof(char));          strcpy(m_Description, f_Description);      }  };  //Declare a gc class  __gc class GCException {  private:      String* m_Description;  public:      __property String* get_Description(){            return m_Description;      }      __property void set_Description(String* f_Description){            m_Description = f_Description;      }  };  void main(){      UnmanagedException objUnmgdException;      GCException * pGCException = new GCException;      try{            for(int i =0;i<=1;i++){                  try{                        switch(i){                        //Throwing unmanaged exception  case 0:  objUnmgdExcepion.SetDescription ("This is an exception of an  unmanaged class");  throw objUnmgdException;                        //Throwing managed exceptions                        case 1:  pGCException->Description = S"This is an exception of a managed  GC class type";                          throw pGCException;                        }                  }  //Catching unmanaged exceptions                  catch(UnmanagedException &objUnmgd){  Console::WriteLine  (objUnmgd.GetDescription());                  }                  //Catching managed exceptions  catch(GCException *pGCException){  Console::WriteLine  (pGCException->Description);                  }            }      }      __finally{  Console::WriteLine  ("The application is now in finally block");      }  } 

Output:

 This is an exception of an unmanaged class  This is an exception of a managed GC class type  The application is now in finally block 

This program should have put to rest all your doubts as to whether unmanaged and managed exceptions can be handled in the same try catch block.

__finally Keyword

Apart from the normal try catch blocks, managed extensions support the __finally block. This block can follow a try or catch clause. After an exception has occurred, the __finally block cleans up any resources that are left. A catch block is executed only when the associated try block throws a managed exception. It should be noted here that unlike the catch block, the __finally block is always executed, even if no exception has occurred.

Unlike in standard C++, where unwinding for C++ objects occurs with destructors that are on the runtime stack between the throwing and handling function, unwinding does not occur in __gc classes . This is because __gc classes are allocated on the heap.

Catching Unmanaged Exceptions

An exception thrown by the unmanaged code is wrapped by the managed extensions and compared with the exceptions specified in the catch block. To catch an exception in managed code, thrown by the unmanaged code, we must be careful in placing more specific catch block first and the generic catch statements down the line to ensure that a specific catch handler is always invoked if available. This means putting catch clauses with all unmanaged types before that of SEHException type and putting catch( ) in the very end.


Snoops

   
Top


Migrating to. NET. A Pragmatic Path to Visual Basic. NET, Visual C++. NET, and ASP. NET
Migrating to. NET. A Pragmatic Path to Visual Basic. NET, Visual C++. NET, and ASP. NET
ISBN: 131009621
EAN: N/A
Year: 2001
Pages: 149

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net