5

If I implement a COM interface in a C# class, which will be called from a C++ module, then in case of a failure the C# code should throw an exception; this will be marshalled to a HRESULT failure code by the interop layer.

But will any message text (or other information) passed to the Exception constructor also be available to the calling C++ code? If so, how can it be obtained i.e. which API methods?

e.g. if in my C# code I do throw new ArgumentException("The email address is invalid") I would except my COM HRESULT to be E_INVALIDARG but will my custom text be marshalled or can I only look up a text description of E_INVALIDARG?

Mr. Boy
  • 60,845
  • 93
  • 320
  • 589
  • We already [went through this](http://stackoverflow.com/a/33037504/17034). – Hans Passant Nov 09 '15 at 16:39
  • You mentioned it in passing in a different question but my search on this interface did not clarify where it is implemented or how I obtain an interface pointer. If your answer is "yes, and you can get it through IErrorInfo" could you flesh that out a little? MSDN is not showing me anything concrete/specific so far. – Mr. Boy Nov 10 '15 at 08:22
  • 1
    @HansPassant it's also not clear in your referenced answer if the message will be a generic mapping to the COM HRESULT, or if the text I pass to a C# exception ctor will be marshalled. e.g `throw new ArgumentException("The email address is invalid")`? – Mr. Boy Nov 10 '15 at 08:25

2 Answers2

2

It's little known that the IErrorInfo object (returned by GetErrorInfo) also implements the _Exception COM interface, which exposes the public members of the System.Exception class to unmanaged code, including StackTrace, etc.

To access _Exception from C++, you'd need to import a correct version of mscorlib.tlb, e.g.:

#import "C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.tlb" raw_interfaces_only
noseratio
  • 59,932
  • 34
  • 208
  • 486
  • I shall investigate this and report back, sounds very interesting. Thanks. – Mr. Boy Nov 11 '15 at 08:19
  • Hmm, you wouldn't be able to provide a code example how to use this would you? The documentation says "This interface is for access to managed classes from unmanaged code" but then only discusses managed code - assemblies, etc. Is this reliant on CLR? If not, what headers are needed? – Mr. Boy Nov 11 '15 at 09:59
  • Cool, thanks. I assume this is accessed through `QueryInterface` as normal? I'm not sure who voted you down or why for this. – Mr. Boy Nov 12 '15 at 09:16
  • @Mr.Boy, you can indeed just use `QueryInterface`, or use ATL and `ComQIPtr<_Exception>`, or remove `raw_interfaces_only` from the `#import` and VC++ should generate COM smart pointers for you. I care less about down-votes without relevant comments :) – noseratio Nov 12 '15 at 11:15
-1

This is generally possible when implementing the interface ISupportErrorInfo

AcidJunkie
  • 1,878
  • 18
  • 21