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?
IUnknown
and nothing else, any reason for that? Just so you know, the act of c# code casting anobject
toISomeInterface
will end up callingQueryInterface
behind 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. – MickyDISomeInterface
is 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_NOINTERFACE
error? 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