如何实现来自本机代码的 .NET 方法回调

本文关键字:本机代码 NET 方法 回调 何实现 实现 | 更新日期: 2023-09-27 18:32:28

我在C#代码中使用Windows CBT钩子,如下所示。这段代码效果很好,但我只是想到我对它的实际工作原理没有清晰的了解。

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

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

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());
    }
}

如何实现来自本机代码的 .NET 方法回调

来自 MSDN:

当委托封送为函数指针时,运行时会分配一个 thunk,用于执行从非托管到托管的转换。此 thunk 是非托管代码在最终调用托管委托之前实际调用的内容。