gpt4 book ai didi

c# - 检测到 CallbackOnCollectedDelegate

转载 作者:可可西里 更新时间:2023-11-01 03:13:01 28 4
gpt4 key购买 nike

我正在对一个应用程序进行子类化。我的子类 Window 过程在一个 DLL 中。我在 DLL 中的子类化代码看起来有点像这样(精简,删除了其他不相关的部分)。

class FooBar
{
private delegate int WndProcDelegateType(IntPtr hWnd, int uMsg,
int wParam, int lParam);

private const int GWL_WNDPROC = (-4);
private static IntPtr oldWndProc = IntPtr.Zero;
private static WndProcDelegateType newWndProc = new
WndProcDelegateType(MyWndProc);

internal static bool bHooked = false;

[DllImport("user32.dll")]
private static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex,
WndProcDelegateType dwNewLong);

[DllImport("user32.dll")]
private static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex,
IntPtr dwNewLong);


[DllImport("user32")]
private static extern int CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hWnd,
int Msg, int wParam, int lParam);

private static int MyWndProc(IntPtr lhWnd, int Msg, int wParam, int lParam)
{
switch (Msg)
{
// the usual stuff


// finally
return CallWindowProc(oldWndProc, lhWnd, Msg, wParam, lParam);
}


internal static void Hook()
{
oldWndProc = SetWindowLong(hWnd, GWL_WNDPROC, MyWndProc);
bHooked = oldWndProc != IntPtr.Zero;
}

internal static void Unhook()
{
if (bHooked) SetWindowLong(hWnd, GWL_WNDPROC, oldWndProc);
}
}

现在,即使我在委托(delegate)的类级静态实例变量中持有对 WndProc 的强引用,我也会收到此错误。

CallbackOnCollectedDelegate was detected

Message: A callback was made on agarbage collected delegate of type'PowerPointAddIn1!FooBar+WndProcDelegateType::Invoke'.This may cause application crashes,corruption and data loss. When passingdelegates to unmanaged code, they must be keptalive by the managed application untilit is guaranteed that they will neverbe called.

我做错了什么?

最佳答案

oldWndProc = SetWindowLong(hWnd, GWL_WNDPROC, MyWndProc);

这会强制 C# 即时创建委托(delegate)对象。它将代码翻译成这样:

oldWndProc = SetWindowLong(hWnd, GWL_WNDPROC, new WndProcDelegateType(MyWndProc));

这是一个问题,该委托(delegate)对象未在任何地方被引用。下一次垃圾收集将销毁它,从非托管代码下面拉出地毯。你已经在你的代码中做了正确的事情,你只是忘记了使用它。修复:

oldWndProc = SetWindowLong(hWnd, GWL_WNDPROC, newWndProc);

顺便说一句,从 NativeWindow 派生您自己的类并使用其 AssignHandle() 方法是更好的捕鼠器。当您看到 WM_DESTROY 消息时调用 ReleaseHandle()。

关于c# - 检测到 CallbackOnCollectedDelegate,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4855513/

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