気が狂いそうな質問があります。私はこのバグを追跡するのに 1 週間を費やしました。ここにあります:
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() の直後に保持され、エラーは発生しません。
私がまったく理解していないのは、古いアンマネージ コードがガベージ コレクションの対象になる理由だと思いますか? それは私を夢中にさせています。前もって感謝します!