1

我在 C# 代码中使用 Windows CBT 挂钩,如下所示。这段代码很好用,但我突然想到我对它的实际工作方式没有清楚的了解。

那么,从非托管 Windows 代码到常规函数指针( CBTProc )的回调如何变成非静态托管成员方法调用,以便我可以this在我的CbtHookProc?

一般来说,我了解 C# 委托如何捕获托管代码中的范围。我的问题是它如何仍然适用于非托管回调。在本机 C++ 中,如果不使用全局变量或 ATL thunk 之类的技巧,这是不可能的。

class CbtHook
{
    delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam);
    HookProc cbtHookProc;
    IntPtr cbtHookId;

    const int WH_CBT = 5;

    [DllImport("user32.dll")]
    static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, uint threadId);

    [DllImport("kernel32.dll")]
    static extern uint GetCurrentThreadId();

    [DllImport("user32.dll")]
    static extern IntPtr CallNextHookEx(IntPtr hhook, int nCode, IntPtr wParam, IntPtr lParam);

    IntPtr CbtHookProc(int nCode, IntPtr wParam, IntPtr lParam)
    {
        // can access 'this' here
        return CallNextHookEx(this.cbtHookId, nCode, wParam, lParam);
    }

    public CbtHook()
    {
        this.cbtHookProc = new HookProc(CbtHookProc);
        this.cbtHookId = SetWindowsHookEx(WH_CBT, this.cbtHookProc, IntPtr.Zero, GetCurrentThreadId());
    }
}
4

1 回答 1

2

来自MSDN

当委托被编组为函数指针时,运行时分配一个 thunk 来完成从非托管到托管的转换。这个 thunk 是在最终调用托管委托之前非托管代码实际调用的内容。

于 2013-09-22T06:09:35.717 回答