Hemant
Hemant

Reputation: 736

Handling exceptions thrown from a .NET dll in C++/MFC app

I am working with a C++ application which is interacting with a C#.NET component through COM. Due to some exceptions thrown from .NET dll my C++ application is crashing despite all exception handling mechanism in place. Is it possible to catch the exceptions thrown by .NET dll, inside C++ code? How?

Upvotes: 1

Views: 1709

Answers (1)

Vagaus
Vagaus

Reputation: 4215

I am not an expert in COM/.NET interoperability but I'd expect that the .NET runtime to never let an exception to leak through a COM method call. Instead, I guess the runtime will convert the exception to an object that implements IErrorInfo interface.

[edited] I just confirmed my hypothesis. The following code prints "A dot net exception..." as I suspected.

// SERVER: C#
using System.Runtime.InteropServices;

namespace COMInteroperability
{
    [Guid("6650E916-B507-483e-9804-8EEDA770F76C")]
    interface IFoo
    {
        [ComVisible(true)]
        string Bar(int value);
    }

    [ClassInterface(ClassInterfaceType.AutoDual)]
    [Guid("92377D62-32CB-4b2b-AE79-B256F54B3E17")]
    public class Foo : IFoo
    {
        public string Bar(int value)
        {
            throw new Exception("A dotnet exception...");
        }
    }
}


// CLIENT: C++
#include "stdafx.h"
#import "G:\temp\COMInteroperability\COMInteroperability\COMInteroperability\bin\Debug\COMInteroperability.tlb" no_namespace names_guids raw_interfaces_only

void CheckResult(HRESULT hr)
{
    if (SUCCEEDED(hr)) return;

    CComPtr<IErrorInfo> error;
    if (FAILED(GetErrorInfo(0, &error))) return;

    if (!error.p) return;

    CComBSTR description;
    error->GetDescription(&description);
    wprintf(description.m_str);
}

int _tmain(int argc, _TCHAR* argv[])
{
    CoInitialize(0);
    {
        CComPtr<_Foo> foo;

        CLSID clsid;
        CLSIDFromString(L"{92377D62-32CB-4b2b-AE79-B256F54B3E17}", &clsid);

        HRESULT hr = foo.CoCreateInstance(clsid);

        CheckResult(hr);
        if (FAILED(hr))
        {
            printf("Error %x", hr);
            return -1;
        }

        CComBSTR ret;
        CheckResult(foo->raw_Bar(10, &ret));
    }
    CoUninitialize();
}

[/edited]

Attach a debugger to your process and take a look into the state of the application when it crashes.

Best

Adriano

Upvotes: 2

Related Questions