C# 防止对委托进行垃圾收集
我目前正试图将C代表委派到C++函数指针,我看了: 然后我看到了一个碰撞C# 防止对委托进行垃圾收集,c#,c++-cli,C#,C++ Cli,我目前正试图将C代表委派到C++函数指针,我看了: 然后我看到了一个碰撞 那么,Microsoft的示例是错误的还是我遗漏了什么?您遗漏了使用调试器对局部变量生存期的影响。附加了调试器后,抖动会标记正在使用的变量,直到方法结束。重要的是要使调试可靠。但是,这也会阻止GC.Collect()调用收集委托对象 在没有调试器的情况下运行程序的发布版本时,此代码将崩溃 有关调试生成行为对垃圾收集器的影响的深入回答,请参见“Alloc”调用添加了对委托的引用,这会阻止GC收集委托。使用完函数指针后,必须保
那么,Microsoft的示例是错误的还是我遗漏了什么?您遗漏了使用调试器对局部变量生存期的影响。附加了调试器后,抖动会标记正在使用的变量,直到方法结束。重要的是要使调试可靠。但是,这也会阻止GC.Collect()调用收集委托对象 在没有调试器的情况下运行程序的发布版本时,此代码将崩溃
有关调试生成行为对垃圾收集器的影响的深入回答,请参见“Alloc”调用添加了对委托的引用,这会阻止GC收集委托。使用完函数指针后,必须保留Alloc返回的句柄并对其调用Free()。委托将在不调用Alloc的情况下被GC’ed。如果不调用GCHandle上的Free(),程序将泄漏。 在调试器中运行时,内存环境略有不同。
有意义吗?你完全正确!即使在调试器中运行发布版本(没有GCHandle::Alloc())也总是会崩溃。谢谢
// MarshalDelegate1.cpp
// compile with: /clr
#include <iostream>
using namespace System;
using namespace System::Runtime::InteropServices;
#pragma unmanaged
// Declare an unmanaged function type that takes two int arguments
// Note the use of __stdcall for compatibility with managed code
typedef int (__stdcall *ANSWERCB)(int, int);
int TakesCallback(ANSWERCB fp, int n, int m) {
printf_s("[unmanaged] got callback address, calling it...\n");
return fp(n, m);
}
#pragma managed
public delegate int GetTheAnswerDelegate(int, int);
int GetNumber(int n, int m) {
Console::WriteLine("[managed] callback!");
return n + m;
}
int main() {
GetTheAnswerDelegate^ fp = gcnew GetTheAnswerDelegate(GetNumber);
GCHandle gch = GCHandle::Alloc(fp);
IntPtr ip = Marshal::GetFunctionPointerForDelegate(fp);
ANSWERCB cb = static_cast<ANSWERCB>(ip.ToPointer());
Console::WriteLine("[managed] sending delegate as callback...");
// force garbage collection cycle to prove
// that the delegate doesn't get disposed
GC::Collect();
int answer = TakesCallback(cb, 243, 257);
// release reference to delegate
gch.Free();
}
IntPtr ip = Marshal::GetFunctionPointerForDelegate(gcnew GetTheAnswerDelegate(GetNumber));