How to map/marshall native exceptions into managed exceptions?

Posted on 2009-05-01
Last Modified: 2013-12-17

I am creating a DLL that contains a native "C++" class "CR", and a managed wrapper class "CM" that wraps around CR via a pointer.  

CR defines and uses "C++" native exceptions.  

In CM, I have created managed versions of the unmanaged exceptions in CR.

The methods in CM that invoke, via CR's pointer, methods in the unmanaged code of CR have try...catch...finally.  For each possible native exception that could be thrown through from the unmanaged method, I have placed a catch.  Inside the catch, I simply throw the managed version of the native exception.  Basically, this is how I am providing the mapping from unmanaged to managed exceptions.  

If I do not catch an unmanaged exception, I expect that an SEH exception will be generated.

From what I have read, this process should work, but whenever I force my native code to throw an unmanaged exception, what I catch in my CM wrapper class is an SEH exception.  Arggg...  So much for me understanding things!  :P

So, I am hoping that someone can tell me the best practices way to marshall exceptions between managed and unmanaged code...  Must I replace my native "C++" code with SEH (hope not)?  Is there an interop method that provides mapping that I must override?  Should I just define managed exceptions in my unmanaged code (i would prefer to keep the worlds separate, if possible)?

I would sincerely appreciate you help with these questions...


Question by:mjgardne

    Author Comment

    So, I've done more testing and the code snippet contains my results and comments...  I am still at a loss as to what is the best practice manner for handling exceptions that cross unmanaged->managed boundaries, and hope that I get some guidance from others who have wrestled with this question.



        // From managed, C++...
        // Calling Test() in the native C++, unmanaged code to make the native, unmanaged code throw one of our C++ exceptions,
        // which are subclassed from std::exception.
    	// This is the C++ base exception class in the native, unmanaged code, and it is a subclass of std::exception
    	// Although, Test() throws this exception from the native code, it 
    	// never reaches the catch statement.
    	catch (CRegistryException& ex)
    		int a=0;
    	// So, next I try to catch any kind of C++ native exception.  Although
    	// Test() in the native code throws a subclass of std::exception, it
    	// never reaches this catch statement.
    	catch (std::exception& ex)
    		int a=0;
    	// For some reason, when Test() throws a subclassed C++ std::exception, it
    	// can be caught here.  When I look at ex in the debugger, it contains
    	// two fields: std::exception and message.  Message is a member is
    	// my native exception subclass so I can pass along a message when it
    	// is thrown.  std::exception contains two fields: _m_doFree and _m_what.
    	// When I did a    throw gcnew System::Exception("Hi")     from the unmanaged code, it
    	// was caught here, but ex was "undefined".  When I subclassed from 
    	// System::Exception and tried to catch the subclass, it caught it, but
    	// ex was undefined.  Why is ex undefined in both cases?  In my 
    	// application, all I care about is catching the unmanaged exceptions so
    	// I can map them to managed ones with localized error messages.  So,
    	// I may be able to live with throwing managed exceptions from native
    	// code, but I still would like to know what is best practice, why
    	// are unmanaged, C++ std::exceptions being caught by catch(Exception ^ex),
    	// and why ex has an "undefined" value.  Arggg...  Why is this so
    	// difficult!  :)
    	catch(Exception ^ex)
    		int a=0;
    	// We never reach this point.
    		int a =0;

    Open in new window

    LVL 19

    Expert Comment

    Is the behavior different if you catch an exception of type System.Runtime.InteropServices.SEHException in the managed code?
    LVL 19

    Expert Comment

    Here is also one article that describes using vectored exception handling to convert Win32 and C++ exceptions to managed exceptions:

    Accepted Solution

    Hi LordOfPorts,

    Thank you for the great articles about vectored exception handling...  When I was Googling for info, I found bits and pieces about this method, but nothing that drew it all together like your suggestion did.  Conceptually, this seems like it would be a valid alternative for passing native exceptions to managed code.  Our application is built upon a layer made of 7 DLLs.  Each DLL has an unmanaged class doing low level work, and a managed class that acts as the interface to higher application levels.  From what I have read, it seems that our entire application would have register the handler and in it is where the translations would happen...  From a reusability and principle of locality point of view, it would be nice to catch them on the individual DLL level...  I have no experience with vectored exceptions, so I will have to see whether they will work at a lower level than an application.  To be honest, from my testing, it appears that I can simply convert my unmanaged exceptions that subclass std::exception to managed exceptions that subclass System::Exception.  When I threw them from natve code, I successfully caught them, by name, in the managed code without any extra work.  I have read many times that it is not an issue to mix natve and managed types, so maybe this is why it works well.  The thing that I do not know is whether this is the preferred solution.  It would work for my needs, but what is the best practice and most current method?  There seem to be thousands of people working on similar projects, but I am amazed that I cannot find a common solution to my question.  Your solution is very interesting, but the KISS principle favors mine...  :P   Anyway, thank you for your great reference and I will try it out over the next few days...  If I hit some walls, I will probably wimp out and simple throw managed exceptions from my unmanaged code.

    Thanks and have a great Tuesday!


    Featured Post

    Free Trending Threat Insights Every Day

    Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

    Join & Write a Comment

    Normally the drop down box control found in the .Net framework tools is able to select just one data and value at a time, which is displayed on the text area.   But what if you want to have multiple values to be selected in the drop down box? As …
    The object model of .Net can be overwhelming at times – so overwhelming that quite trivial tasks often take hours of research. In this case, the task at hand was to populate the datagrid from SQL Server database in Visual Studio 2008 Windows applica…
    In this sixth video of the Xpdf series, we discuss and demonstrate the PDFtoPNG utility, which converts a multi-page PDF file to separate color, grayscale, or monochrome PNG files, creating one PNG file for each page in the PDF. It does this via a c…
    This video discusses moving either the default database or any database to a new volume.

    734 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    18 Experts available now in Live!

    Get 1:1 Help Now