gpt4 book ai didi

c# - 从 C# 访问 COM vtable

转载 作者:太空狗 更新时间:2023-10-29 20:11:53 24 4
gpt4 key购买 nike

在 C# 中有没有什么方法可以访问 COM 对象的虚方法表以获得函数的地址?

最佳答案

经过大量搜索和拼凑不同的部分解决方案后,我想出了如何去做。

首先您需要为您尝试访问的对象定义 COM 组件类:

[ComImport, Guid("..."), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface ISomeCOMInterface
{
// Define interface methods here, using PInvoke conversion between types
}

接下来您需要实例化 COM 对象。有几种方法可以做到这一点。因为我对 DirectSound 感兴趣,所以我使用了:

[DllImport("dsound.dll", EntryPoint = "DirectSoundCreate", ...]
static extern void DirectSoundCreate(IntPtr GUID, [Out, MarshalAs(UnmanagedType.Interface)] out IDirectSound directSound, IntPtr pUnkOuter);

IDirectSound directSound;
DirectSoundCreate(IntPtr.Zero, out directSound, IntPtr.Zero);

既然我现在有了我的 COM 对象,我就可以使用 Hans 关于 Marshal.GetComInterfaceForObject() 的建议:

IntPtr comPtr = Marshal.GetComInterfaceForObject(directSound, typeof(IDirectSound));
IntPtr vTable = Marshal.ReadIntPtr(comPtr);

作为额外的好处,您可以像这样遍历 vtable 函数:

int start = Marshal.GetStartComSlot(typeof(IDirectSound));
int end = Marshal.GetEndComSlot(typeof(IDirectSound));

ComMemberType mType = 0;
for (int i = start; i <= end; i++)
{
System.Reflection.MemberInfo mi = Marshal.GetMethodInfoForComSlot(typeof(IDirectSound), i, ref mType);
Console.WriteLine("Method {0} at address 0x{1:X}", mi.Name, Marshal.ReadIntPtr(vTable, i * Marshal.SizeOf(typeof(IntPtr))).ToInt64());
}

额外阅读/引用资料:

关于c# - 从 C# 访问 COM vtable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3504848/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com