【发布时间】:2011-12-25 13:07:55
【问题描述】:
我正在编写一些测试代码来模拟调用我的后期绑定 COM 对象的 c# 实现的非托管代码。我有一个声明为 IDispatch 类型的接口,如下所示。
[Guid("2D570F11-4BD8-40e7-BF14-38772063AAF0")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface TestInterface
{
int Test();
}
[ClassInterface(ClassInterfaceType.AutoDual)]
public class TestImpl : TestInterface
{
...
}
当我使用下面的代码调用 IDispatch 的 GetIDsOfNames 函数时
..
//code provided by Hans Passant
Object so = Activator.CreateInstance(Type.GetTypeFromProgID("ProgID.Test"));
string[] rgsNames = new string[1];
int[] rgDispId = new int[1];
rgsNames[0] = "Test";
//the next line throws an exception
IDispatch disp = (IDispatch)so;
IDispatch 定义为:
//code provided by Hans Passant
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("00020400-0000-0000-C000-000000000046")]
private interface IDispatch {
int GetTypeInfoCount();
[return: MarshalAs(UnmanagedType.Interface)]
ITypeInfo GetTypeInfo([In, MarshalAs(UnmanagedType.U4)] int iTInfo, [In, MarshalAs(UnmanagedType.U4)] int lcid);
void GetIDsOfNames([In] ref Guid riid, [In, MarshalAs(UnmanagedType.LPArray)] string[] rgszNames, [In, MarshalAs(UnmanagedType.U4)] int cNames, [In, MarshalAs(UnmanagedType.U4)] int lcid, [Out, MarshalAs(UnmanagedType.LPArray)] int[] rgDispId);
}
抛出 InvalidCastException。是否可以将 c# 接口转换为 IDispatch?
【问题讨论】:
-
只有在 C# 接口实际上是从 IDispatch 派生的情况下才能成功,而从您提供的代码 n-ps 不是这种情况...
-
@Yahia - 谢谢。如果使用实现 IDispatch 的非托管 COM 对象的 ProgID,我不确定为什么相同的 cast sn-p 会成功?
-
因为 COM 对象实际上是从 IDispatch 派生的 - 如果 .NET 运行时看到您访问托管 COM 对象(尤其是如果它使用相同的运行时版本)
-
好的,但这不是 [InterfaceType(ComInterfaceType.InterfaceIsDual)] 的重点,它“指示接口作为双接口向 COM 公开,它启用了早期和后期绑定。”
-
是的,但同样:IIRC .NET 运行时在使用托管代码中的托管 COM 对象时表现不同...为什么不用非托管代码模拟 COM 对象?