创建 IDispatch .NET COM 类,其中内容仅在运行时可用
Posted
技术标签:
【中文标题】创建 IDispatch .NET COM 类,其中内容仅在运行时可用【英文标题】:Create IDispatch .NET COM class where content is available only at runtime 【发布时间】:2010-11-18 04:45:03 【问题描述】:我目前正在将一些代码从本机 C++ 迁移到托管 C++(纯)。该代码涉及与 Windows Active Scripting 的交互。目前我们的原生代码提供了一个 名为“ObjectDispatch”的类实现了“IDispatch”(使用 ATL)。此类实现在运行时查询我们自己的本机类“Object”以确定它支持哪些方法和属性,然后将任何“IDispatch::Invoke”调用转发给该“Object”。
我已经看到使用支持“IDispatch”的 .NET COM 互操作的示例,但是这些实现要么源自 IDL,要么基于规范 .NET 类,它们都不会在运行时发生。
.NET COM 互操作似乎可以生成“IDispatch”的实现 如果您在给定类上使用以下属性,则在编译时:
[ClassInterface(ClassInterfaceType::AutoDispatch)]
我假设我可以在运行时动态生成一个支持该属性的类。但是,在我尝试之前,我想知道是否有人有任何想法 如何通过与本机代码一起使用的类似方式来实现这一点。
请注意,此时“Object”类仍保留为原生类。
【问题讨论】:
我已经多次回到这个问题,我真的不明白你在问什么......你有一个通过 IDispatch 公开的本机对象模型,并且想要从托管代码中使用它? 是的,你是对的。我想更好的标题应该是“我可以直接在 .net 中实现 IDispatch 吗?”。 【参考方案1】:从微软那里得到了一些“可能”有效的官方反馈。没有时间确认,但如果有人感兴趣,最好发帖。
[Guid("00020400-0000-0000-c000-000000000046"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IDispatch
int GetTypeInfoCount();
ITypeInfo GetTypeInfo(
[MarshalAs(UnmanagedType.U4)] int iTInfo,
[MarshalAs(UnmanagedType.U4)] int lcid);
[PreserveSig]
int GetIDsOfNames(
ref Guid riid,
[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr)] string[] rgsNames,
int cNames,
int lcid,
[MarshalAs(UnmanagedType.LPArray)] int[] rgDispId);
[PreserveSig]
int Invoke(
int dispIdMember,
ref Guid riid,
[MarshalAs(UnmanagedType.U4)] int lcid,
[MarshalAs(UnmanagedType.U4)] int dwFlags,
ref System.Runtime.InteropServices.ComTypes.DISPPARAMS pDispParams,
[Out, MarshalAs(UnmanagedType.LPArray)] object[] pVarResult,
ref System.Runtime.InteropServices.ComTypes.EXCEPINFO pExcepInfo,
[Out, MarshalAs(UnmanagedType.LPArray)] IntPtr[] pArgErr);
class IImplimentIDispatch : IDispatch
public IImplimentIDispatch(object o)
_o = o;
…
【讨论】:
以上是关于创建 IDispatch .NET COM 类,其中内容仅在运行时可用的主要内容,如果未能解决你的问题,请参考以下文章
COM 互操作 (CCW) 中的重载 - IDispatch 名称包括后缀(_2、_3 等)
LPDISPATCH是啥数据类型,他和IDispatch有啥关系