我目前正在試圖獲取一個C#委託C++函數指針,我看着example from Microsoft:防止委託
// 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();
}
的調用的GCHandle ::的Alloc()是應該阻止垃圾收集器收集委託。但我的理解是,變量GetTheAnswerDelegate^fp已經使委託保持活着狀態,因爲它是一個根對象,並且即使當我刪除對GCHandle的調用時,該例仍然有效。只有當我內聯這樣的代表實例:
IntPtr ip = Marshal::GetFunctionPointerForDelegate(gcnew GetTheAnswerDelegate(GetNumber));
然後我看到崩潰。
所以是微軟的例子錯誤還是我錯過了什麼?
你是完全正確的!即使在調試器中運行發佈版本(無GCHandle :: Alloc())也會崩潰。謝謝! – BugSlayer 2013-05-14 13:57:16