I have a .NET CCW that implements an interface method with the following signature
[PreserveSig]
HRESULT GetKeyValue(
[In, MarshalAs(UnmanagedType.LPWStr)] string key,
[Out, MarshalAs(UnmanagedType.Interface)] out IModelObject @object,
[Out, MarshalAs(UnmanagedType.Interface)] out IKeyStore metadata);
When I pass my CCW to a native module that I don’t control, it tries to call this method as follows
(*(*ccw + 40i64))(ccw, L"ActionName", &object, 0i64); // GetKeyValue
The last parameter has been set to NULL
. When the CLR attempts to marshal these parameters to my managed method, in IL_STUB_COMtoCLR
it crashes because R9 (the fourth parameter) is null. If I lie and remove the out IKeyStore metadata
parameter from my managed interface method definition, it doesn’t crash, confirming that this is indeed the issue.
When COM objects are implemented in C++, it’s a fairly common pattern to have optional parameters that you can pass NULL
to, which the COM object will check for to determine whether it needs to do any work for that parameter, so I’m not sure whether I’m just missing how you would work around this, or if indeed this is an oversight in the design of built-in .NET Marshaller?