SEH and C++ Exceptions - catch all in one | CodeGuru

SEH and C++ Exceptions – catch all in one

. Environment:  Visual C++ 5.0 & SP3, Windows NT 4.0 & SP5, Unicode, MBCS This article describes how to handle SE and C++ exception together. Motivation Everybody sometimes need to write as robust code as possible. The simplest way, in these cases, is to use exception handling. But most code is wrote in C++/MFC, with […]

Written By
CodeGuru Staff
CodeGuru Staff
May 30, 1999
3 minute read
CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More

.


Environment:
  Visual C++ 5.0 & SP3, Windows NT 4.0 & SP5, Unicode, MBCS

This article describes how to handle SE and C++ exception together.

Motivation

Everybody sometimes need to write as robust code as possible. The simplest way, in
these cases, is to use exception handling. But most code is wrote in C++/MFC, with C++
exception handling (e.g. CdbException). With SEH, it is not possible to
catch C++ exception, and C++ typed exception can not catch SE selectively, because it is
not typed in a way of C++. Solution with catch(…) is not
useful, because you will not know ‘type’ of exception. SE is possible to catch like
unsigned int typed C++ exception, but this solution is not very nice.  

Description of solution

I was looking for a method to handle SE and C++ exception together. I found function

  typedef void (*_se_translator_function)( unsigned int, struct _EXCEPTION_POINTERS* );

In MSDN you can find following description:

The _set_se_translator function provides a way
to handle Win32 exceptions (C structured exceptions) as C++ typed exceptions. To allow
each C exception to be handled by a C++ catch handler, first
define a C exception "wrapper" class that can be used, or derived from, in order
to attribute a specific class type to a C exception. To use this class, install a custom C
exception translator function that is called by the internal exception-handling mechanism
each time a C exception is raised. Within your translator function, you can throw any
typed exception that can be caught by a matching C++ catch
handler.

And now, it is enough to write wrapper class (I think, my class is quite better than
class provided by documentation for _set_se_translator):

  class CSeException : public CException
  {
      DECLARE_DYNAMIC(CSeException)
  public:
      CSeException(UINT nSeCode, _EXCEPTION_POINTERS* pExcPointers);
      CSeException(CSeException & CseExc);

      UINT GetSeCode(void);
      _EXCEPTION_POINTERS* GetSePointers(void);
      PVOID GetExceptionAddress(void);

      void Delete(void);
      int ReportError(UINT nType = MB_OK, UINT nIDHelp = 0);
      BOOL GetErrorMessage(CString & CsErrDescr, PUINT pnHelpContext = NULL);
      BOOL GetErrorMessage(LPTSTR lpszError, UINT nMaxError, PUINT pnHelpContext = NULL);
  private:
      UINT m_nSeCode;
      _EXCEPTION_POINTERS* m_pExcPointers;
  };

And my own translator function:

  void SeTranslator(UINT nSeCode, _EXCEPTION_POINTERS* pExcPointers)
  {
      throw new CSeException(nSeCode,pExcPointers);
  }

How does it work?

When SE is raised, then it is called our own translator function – if it was installed
through _se_translator_function. This translator
function simply throw exception again, but now it is our wrapper class exception filled
with useful information.

Description of CSeException

CSeException class is based on CException class
provided by MFC. I overwrite some of useful methods, but it is working same way like any
other exception class based on CException class – you can find
description in documentation provided by Visual C++.

Usage

At first of all you need to install SeTranslator function, in every
thread of your application. Translator function is  thread specific, it means it is
not globally set in application. In single thread application it is possible to install it
in constructor of application class (as I do in demo program), however in multithreading
application it is best place to install translator function at the beginnings of every
thread. When translator function is installed, then it is possible to write code like
this:

  char *p = NULL;

  try {

  // do something ...

  p[0] = 0;

  // do something ...

  } catch (CdbException dbError) {

  //handle it

  } catch(CSeException *e) {
  e->ReportError(MB_OK | MB_ICONSTOP);
  e->Delete();
  }

CSeException class is Unicode and MBCS strings compliant. Please note,
delete CSeException in catch() block,
because it is dynamically allocated by translator function.

Download

Download demo project – 16 KB

Download source – 2 KB

CodeGuru Logo

CodeGuru covers topics related to Microsoft-related software development, mobile development, database management, and web application programming. In addition to tutorials and how-tos that teach programmers how to code in Microsoft-related languages and frameworks like C# and .Net, we also publish articles on software development tools, the latest in developer news, and advice for project managers. Cloud services such as Microsoft Azure and database options including SQL Server and MSSQL are also frequently covered.

Property of TechnologyAdvice. © 2026 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.