I'm working with a native C++ dll from C#. On the C++ side there's a class that only implements one interface and IUnknown but its QueryInterface returns E_NOINTERFACE for anything other than IUnknown.
On the C# side I'm calling a method in the dll that returns an instance of this class, but even if I declare the parameter as ISomeInterface .NET still calls QueryInterface which results in an exception. E.g.:
[ComImport, Guid(" ... ")]
public interface ISomeInterface { ... }
[DllImport("mylib.dll")]
public static extern void GetThing([MarshalAs(UnmanagedType.Interface)] out ISomeInterface thing);
calling GetThing throws InvalidCastException with message "This operation failed because the QueryInterface call on the COM component for the interface with IID '{ ... }' failed due to the following error: No such interface supported (Exception from HRESULT: 0x800040002 (E_NOINTERFACE))."
If I change the type to object
public static extern void GetThing([MarshalAs(UnmanagedType.Interface)] out object thing);
..then calling GetThing succeeds but trying to cast the resulting System.__ComObject to ISomeInterface throws the same exception.
I tried every different InterfaceType attribute on the interface definition but always get the same exception.
I also tried defining the interface as an abstract class:
[ComImport, Guid(" ... "), ClassInterface(ClassInterfaceType.None)]
public abstract class ISomeInterface { ... }
Calling GetThing then succeeds and I get an instance of ISomeInterface but as soon as I call any method it throws a BadImageFormatException with message "Bad IL format."
And I tried every different ClassInterfaceType attribute with the same results.
Is there any way this class can be used from C# without modifying the C++ code to fix its QueryInterface implementation?
IUnknownand nothing else, any reason for that? Just so you know, the act of c# code casting anobjecttoISomeInterfacewill end up callingQueryInterfacebehind the scenes (when the object is a COM object of course) so that is to be expected. If you have access to the c++ code you should fix it. - MickyDISomeInterfaceis the default interface so they're able to use it withoutQueryInterface- I'll change the C++ as well but would ideally get it working with this version for compatibility - gordyE_NOINTERFACEerror? Anyway, try updating the c++ code, due to the nature of COM it is unlikely you'll break compatibility unless you change GUIDs; interfaces etc which in this case is not a requirement - MickyD