2010-04-22 75 views
0

编辑:在c中访问一个com对象的vtable#

我试图在.net类中封装第三方com对象,同时修复它的错误。我希望能够通过调用我自己的方法来替换com对象的vtable中的一个方法,从而提供该方法的无bug实现。

我试图在非常基本的东西上测试这一点,但给出下面的答案我完全是错误的轨道。通过创建一个对我的com对象的引用,我假设我已经创建了一个运行时可调用的包装器,有什么方法可以获得一个指向真正的基础com对象的指针吗?


我试图访问一个com对象的vtable在内存中,并越来越无处。

从我读到的内容中,com对象的前4个字节应该是指向vtableptr的指针,而vtableptr又是指向vtable的指针。

尽管我不确定我是否期望在这个com对象的槽7中找到我的测试方法,但我已经试过了它们,没有看起来像我的函数的地址。

如果任何人都可以对此示例进行必要的更改以使其正常工作(目的只是尝试通过访问com对象的vtable并在其中找到该行的方法来调用Tester类上的Test方法) )我会很感激。

我知道这是罕见的,任何人都需要做,但请接受我确实需要做的相当类似,并已预先考虑的替代方案

感谢

[ComVisible(true)] 
public class Tester 
{ 
    public void Test() 
    { 
     MessageBox.Show("Here"); 
    } 

} 

public delegate void TestDelegate(); 

private void main() 
{ 

    Tester t = new Tester(); 

    GCHandle objectHandle = GCHandle.Alloc(t); 

    IntPtr objectPtr = GCHandle.ToIntPtr(objectHandle); 

    IntPtr vTable = (IntPtr)Marshal.ReadInt32(objectPtr); 

    IntPtr vTablePtr = (IntPtr)Marshal.ReadInt32(vTable); 

    IntPtr functionPtr = (IntPtr)Marshal.ReadInt32(vTablePtr, 7 * 4); // 7 may be incorrect but i have tried many different values 

    TestDelegate func = (TestDelegate)Marshal.GetDelegateForFunctionPointer(functionPtr, typeof(TestDelegate)); 

    func(); 

    objectHandle.Free(); 
} 

回答

3

你完全在这个错误的轨道上。 t对象是而不是的一个COM接口指针,它是一个.NET对象引用。直到非托管代码创建CCW(COM可调用包装器),才会创建COM接口指针(及其v-表)。它具有为非托管代码,CLR互操作层不允许托管代码创建CCW。

保持这个线程移动的唯一方法是解释你为什么要这么做。

+0

感谢汉斯的你的解释,我绝对没有在这里深度,这节省了我浪费时间的东西,永远不会工作。我已更新我的问题,并提供更多信息,以防有人提供建议 – 2010-04-22 22:46:29

0

@Hans有一点。 +1。

这是在任何形式的解决方案,只是一个解释:

如果你真的想访问一个COM对象,为什么不创建一个简单的COM DLL,然后尝试访问它?

互操作工作的方式有两种:

  1. .NET组件调用COM组件
  2. COM组件调用.NET组件

当.NET调用COM它需要Runtime Callable Wrapper(Visual Studio将创建为你)和COM Callable Wrapper(需要装饰.NET成员ComVisible)为后者。

要从.NET访问COM对象的vtable,它需要是您正在访问的真正COM组件,否则它只是@Hans提到的对象引用。