我正在使用来自C#的本机C# dll。在C++方面,有一个类只实现一个接口和IUnknown,但是它的QueryInterface返回的是除了IUnknown以外的任何东西的E_NOINTERFACE。
在C#方面,我在dll中调用一个方法,该方法返回该类的一个实例,但即使我将参数声明为ISomeInterface,.NET仍然调用QueryInterface,这将导致异常。例如:
[ComImport, Guid(" ... ")]
public interface ISomeInterface { ... }
[DllImport("mylib.dll")]
public static extern void GetThing([MarshalAs(UnmanagedType.Interface)] out ISomeInterface thing);调用GetThing会抛出消息“此操作失败,因为IID '{ . }‘接口的COM组件的QueryInterface调用失败,原因是以下错误:不支持此类接口( HRESULT: 0x800040002 (E_NOINTERFACE)例外)。”
如果我将类型更改为对象
public static extern void GetThing([MarshalAs(UnmanagedType.Interface)] out object thing);..then调用GetThing成功,但尝试将结果System.__ComObject转换为ISomeInterface会引发相同的异常。
我尝试了接口定义上的每个不同的InterfaceType属性,但是总是得到相同的异常。
我还尝试将接口定义为一个抽象类:
[ComImport, Guid(" ... "), ClassInterface(ClassInterfaceType.None)]
public abstract class ISomeInterface { ... }然后调用GetThing就成功了,我得到了一个ISomeInterface实例,但是一旦调用任何方法,它就会抛出一个带有消息“坏IL格式”的BadImageFormatException。
我用相同的结果尝试了每个不同的ClassInterfaceType属性。
是否可以在不修改C#代码来修复其QueryInterface实现的情况下从C++中使用该类?
发布于 2016-04-05 03:36:18
通过您提到的这种方法:
public static extern void GetThing([MarshalAs(UnmanagedType.Interface)] out object thing);...assuming您正在使用的.NET 4+尝试如下:
object thing;
GetThing (out thing); // prefix me with the class defining the `DllImport`
dynamic d = thing;
d.DoSomething(); // CHANGE DoSomething() to a known method that ISomeInterface exposes使用COM的dynamic的行为是不需要提前提供类库。当您为动态对象上的方法键入代码时,将不会在Visual中看到语句完成/智能感知,但是代码将编译。它将在运行时进行评估。希望这将绕过QueryInterface(),并将使用您所指示的COM类所使用的default(ISomeInterface )。
执行部分:
在C++端,ISomeInterface是默认接口
执行部分:
...but我仍然感兴趣的是,不需要发布这个dll的新的/非官方的构建,就可以让它正常工作。
如果此操作有效,则不需要更改COM DLL。
https://stackoverflow.com/questions/36415427
复制相似问题