개발자!
나는 아주 이상한 문제가있다. 내 프로젝트에는 C++로 작성된 DLL과 C#으로 작성된 GUI가 있습니다. 일부 상호 운용성을 위해 콜백을 구현했습니다. 나는 C++ dll이 어떤 상황에서는 C# 코드를 호출 할 것을 계획했다. 그것은 작동하지만 ... 오래 걸리지 않고 이유를 이해할 수 없습니다. C 번호 부분에 주석으로 표시된 문제는 여기에
단순화 된 샘플의 전체 코드 :C#에서의 C++ 콜백 중 NullReferenceException
C++ DLL :
#include <SDKDDKVer.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
extern "C"
{
typedef void (*WriteSymbolCallback) (char Symbol);
WriteSymbolCallback Test;
_declspec(dllexport) void InitializeLib()
{
Test = NULL;
}
_declspec(dllexport) void SetDelegate(WriteSymbolCallback Callback)
{
Test = Callback;
}
_declspec(dllexport) void TestCall(const char* Text,int Length)
{
if(Test != NULL)
{
for(int i=0;i<Length;i++)
{
Test(Text[i]);
}
}
}
};
C 번호 부분 :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace CallBackClient
{
class Program
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void WriteToConsoleCallback(char Symbol);
[DllImport("CallbackSketch.dll",CharSet=CharSet.Ansi,CallingConvention=CallingConvention.Cdecl)]
private static extern void InitializeLib();
[DllImport("CallbackSketch.dll",CharSet=CharSet.Ansi,CallingConvention=CallingConvention.Cdecl)]
private static extern void SetDelegate(WriteToConsoleCallback Callback);
[DllImport("CallbackSketch.dll",CharSet=CharSet.Ansi,CallingConvention=CallingConvention.Cdecl)]
private static extern void TestCall(string Text,int Length);
private static void PrintSymbol(char Symbol)
{
Console.Write(Symbol.ToString());
}
static void Main(string[] args)
{
InitializeLib();
SetDelegate(new WriteToConsoleCallback(PrintSymbol));
string test = "Hello world!";
for (int i = 0; i < 15000; i++)
{
TestCall(test, test.Length);// It crashes when i == 6860!!!! Debugger told me about System.NullReferenceException
}
}
}
}
문제는 6천8백60번째에 충돌이다 되풀이! 나는 그 문제가 그 주제에 대한 나의 지식의 부족이라고 믿는다. 누군가가 나를 도울 수 있었 니?
'GC.KeepAlive'가 무엇인지 유의하십시오. – Yogu
아주 특별한 경우에 작동 할 수 있습니다. –