gpt4 book ai didi

c# - wndproc 上的 SetWindowLong 导致旧的 wndproc 被垃圾收集

转载 作者:太空狗 更新时间:2023-10-29 23:52:04 25 4
gpt4 key购买 nike

我有一个让我抓狂的问题。我花了一个星期的时间来追查这个错误,可能只是我对互操作的理解不如我想的那样。在这里:

 public class User
{
public const int GWL_WNDPROC = -4;

[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, User.WindowProc newProc);

[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

public delegate IntPtr WindowProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);

}

那是我的基本 User32 包装器。现在这样称呼:

class MyClass
{
private User.WindowProc proc;

public void MyMethod()
{
proc = new User.WindowProc(WndProc);

old_window_proc = User.SetWindowLong(handle,User.GWL_WNDPROC,proc);
}

}

强制垃圾回收:

   GC.Collect();
GC.WaitForPendingFinalizers();

然后这样调用:

User.CallWindowProc(old_window_proc,hWnd,   (uint)message.Msg,message.WParam,message.LParam);

我收到一个 *CallbackOnCollectedDelegate * 错误。为什么存在于旧 Winproc 指针处的非托管代码会被 GC 处理?如果我添加这个:

oldProcHolder = (User.WindowProc)Marshal.GetDelegateForFunctionPointer(old_window_proc, typeof(User.WindowProc));

在 SetWindowLong() 之后,它会保留它并且没有错误。

我想我完全不理解的是为什么旧的非托管代码有资格进行垃圾回收?这让我发疯。提前致谢!

最佳答案

GetDelegateForFunctionPointer 函数在使用时将非托管函数转换为托管代码,即委托(delegate)。由于任何委托(delegate)都是托管代码,因此垃圾收集过程会自动运行。因此 GetDelegateForFunctionPointer 函数符合自动垃圾收集的条件。

关于c# - wndproc 上的 SetWindowLong 导致旧的 wndproc 被垃圾收集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13011755/

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