나는 현재 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));
나는 충돌이 표시됩니다.
Microsoft의 예가 잘못 되었나요?
정말 옳았습니다! 릴리스 빌드 (GCHandle :: Alloc()없이)를 실행하면 디버거에서도 항상 오류가 발생합니다. 감사! – BugSlayer