1

Suppose that my application is composed of 3 components. They are:

  1. c++ native library
  2. c++ cli managed library, which wraps native library
  3. c# gui application.

As I understand, any native exception, thrown from a native c++ library will be wrapped with SEHException managed class. I am interested in the next steps, what is recommended to do after the creation of such an exception object.

Should I catch all such possible exceptions within the c++ cli managed library then create an appropriate managed exception? Something like this:

void some_managed_action()
{
    try
    {
       native_object->some_native_action();
    }
    catch (const NativeException& e)
    {
       // What should I do with exception e and native object? before throwing new managed exception
       // Will SEH wrapper automatically delete native exception object
       // delete all native objects?
       throw gcnew ManagedException(get_message(e));
    }
}

Maybe there are some pitfalls in such an approach? Thanks for any advice.

3
  • There is no obvious reason to change anything in this code. Other than the exception type name perhaps, "UnmanagedException" would make a lot more sense since that's where it came from. Very unlikely that the C# code can do anything reasonable with it other than error reporting, the more detail you can provide the better. Commented Nov 7, 2016 at 16:02
  • @Hans Passant, As I understood, catching exception by native object is more preferable than by approp. wrapped managed one? docs says: If an unmanaged type is caught by catch(Object^), it will not destroy the thrown object. Commented Nov 7, 2016 at 16:08
  • 1
    When you write "NativeException" in your snippet then everybody will assume that is a native C++ type. Not only is that just fine, it is required to get any info out of the exception object. Passing exceptions without any relevant info at all is a very, very bad idea. It will still work but of course your C# code can't do anything but terminate the program. So whether or not the native exception object is leaked doesn't matter at all. Commented Nov 7, 2016 at 16:18

1 Answer 1

1

Use

try 
{
} 
catch (Exception ex) 
{
    // .NET exception
} 
catch 
{
    // native exception
}

A catch block that handles Exception catches all Common Language Specification (CLS) compliant exceptions. However, it does not catch non-CLS compliant exceptions. Non-CLS compliant exceptions can be thrown from native code or from managed code that was generated by the Microsoft intermediate language (MSIL) Assembler. Notice that the C# and Visual Basic compilers do not allow non-CLS compliant exceptions to be thrown and Visual Basic does not catch non-CLS compliant exceptions. If the intent of the catch block is to handle all exceptions, use the following general catch block syntax.

C#: catch {}

CA2102: Catch non-CLSCompliant exceptions in general handlers

Sign up to request clarification or add additional context in comments.

3 Comments

It is good mention, I did not know, that exception raised by managed c++ should be wrapped by RuntimeWrappedException (not SEHException).
It doesn't make much sense, native code is never going to throw a managed exception. Heaven forbid that it ever does happen. Luckily the CLR will most likely treat it like a CSE (corrupted state exception) so it will never catch.
@HansPassant I don't know if your comment was written to me, but from your content I think it is suppose for the op. The op probably read this article: msdn.microsoft.com/en-us/library/ms404228.aspx and because of that he mentions the RuntimeWrappedException

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.