问题描述
C#中是否有任何方法访问COM对象的虚方法表以获取函数的地址?
Is there any way in C# to access a COM object's virtual method table in order to get a function's address?
推荐答案
经过大量的搜索和拼凑不同的部分解决方案,我想出了如何做。
After a lot of searching and piecing together different partial solutions, I figured out how to do it.
首先,您需要为要尝试访问的对象定义COM coclass:
First you need to define the COM coclass for the object you're trying to access:
[ComImport, Guid("..."), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface ISomeCOMInterface
{
// Define interface methods here, using PInvoke conversion between types
}
接下来需要实例化COM对象。有几种方法可以做到这一点。由于我对DirectSound感兴趣,我使用了:
Next you need to instantiate the COM object. There are a couple of ways to do that. Since I was interested in DirectSound, I used:
[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()
:
Since I now had my COM object, I could then use Hans' suggestion of Marshal.GetComInterfaceForObject()
:
IntPtr comPtr = Marshal.GetComInterfaceForObject(directSound, typeof(IDirectSound));
IntPtr vTable = Marshal.ReadIntPtr(comPtr);
作为一个额外的好处,你可以这样遍历vtable函数:
As an added bonus, you can then iterate through the vtable functions like this:
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());
}
额外阅读/参考:
- [关于COM coclass声明的信息]
- [有关VTables和COM in general]
- [特定于DirectSound COM接口的信息]
- http://msdn.microsoft.com/en-us/library/aa645736(VS.71).aspx [Info on COM coclass declarations]
- http://www.codeproject.com/KB/COM/com_in_c1.aspx [Info on VTables and COM in general]
- http://naudio.codeplex.com/ [Info specific to the DirectSound COM Interfaces]
这篇关于访问COM vtable从C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!