问题与以下线程有关: Access COM vtable from C#
我要做的是通过来自 c# 的方法指针从 com 对象调用方法
我知道方法指针不是必需的,但在这种特殊情况下它是必需的。
为什么我需要方法指针?
我想通过后期绑定从 Word.Content Control 访问 SetPlaceholderText 方法。.NET->COM 中的所有后期绑定功能都使用 IDispatch 接口中的 Invoke 方法,从 com 对象实现。Word.ContentControl 类中的 Invoke 方法有 bug!它可以早期绑定,因为互操作运行时避免调用并使用方法指针。(这也是我想要处理的问题)。它不可能使用带有 vb 后期绑定、c# 动态或 GetType().Invoke 的方法...
我使用链接帖子中的代码作为模板:
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void SetPlaceHolderTextCallback(
[MarshalAs(28)] [In] object BuildingBlock = null,
[MarshalAs(28)] [In] object Range = null,
[MarshalAs(19)] [In] string Text = "");
object contentControl = GetContentControlProx();
IntPtr comPtr = Marshal.GetComInterfaceForObject(contentControl,
typeof(ContentControl));
IntPtr vTable = Marshal.ReadIntPtr(comPtr);
int start = Marshal.GetStartComSlot(typeof(ContentControl));
int end = Marshal.GetEndComSlot(typeof(ContentControl));
SetPlaceHolderTextCallback invoker = null;
ComMemberType mType = MemberTypes.Method;
for (int i = start; i < end; i++)
{
System.Reflection.MemberInfo mi =
Marshal.GetMethodInfoForComSlot(typeof(ContentControl), i, ref mType);
if (mi.Name == "SetPlaceholderText")
{
IntPtr methodPointer = Marshal.ReadIntPtr(vTable, i *
Marshal.SizeOf(typeof(IntPtr)));
invoker = Marshal.GetDelegateForFunctionPointer(methodPointer,
typeof(SetPlaceHolderTextCallback)) as SetPlaceHolderTextCallback;
break;
}
}
invoker(Type.Missing, Type.Missing, "helloWorld");
调用失败并出现 AccessViolationException。我暂时不知道......