Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 防止对委托进行垃圾收集_C#_C++ Cli - Fatal编程技术网

C# 防止对委托进行垃圾收集

C# 防止对委托进行垃圾收集,c#,c++-cli,C#,C++ Cli,我目前正试图将C代表委派到C++函数指针,我看了: 然后我看到了一个碰撞 那么,Microsoft的示例是错误的还是我遗漏了什么?您遗漏了使用调试器对局部变量生存期的影响。附加了调试器后,抖动会标记正在使用的变量,直到方法结束。重要的是要使调试可靠。但是,这也会阻止GC.Collect()调用收集委托对象 在没有调试器的情况下运行程序的发布版本时,此代码将崩溃 有关调试生成行为对垃圾收集器的影响的深入回答,请参见“Alloc”调用添加了对委托的引用,这会阻止GC收集委托。使用完函数指针后,必须保

我目前正试图将C代表委派到C++函数指针,我看了:

然后我看到了一个碰撞


那么,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));