アンマネージドc++dllをインポートするac#マネージドプロジェクトがあります。私が望んでいたのは、C#コードで記述したロギング関数を使用してロギングを機能させることでした。そこで、C#側に次を追加しました。
public struct API
{
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void FunctionPointer(string msg);
[DllImport("mydll.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
unsafe public static extern void setLoggerPointer(IntPtr fctPointer);
[DLLImport("mydll.dll", SetLastError = true)]
[return: MarshalAsAttribute(UnmanagedType.I1)] unsafe public static extern bool init();
}
public unsafe class MyInterface
{
public MyInterface()
{
API.FunctionPointer loggerDelegate;
loggerDelegate = new API.FunctionPointer(Logger.LogMessage);
IntPtr loggerPtr = Marshal.GetFunctionPointerForDelegate(loggerDelegate);
API.setLoggerPointer(loggerPtr);
if (API.init())
{
//do stuff
}
}
}
これが私のロガークラスの定義です:
public static class Logger
{
public static void LogMessage(string msg)
{
Console.WriteLine(msg);
fileStream.Write(msg);
}
}
私はc++側のヘッダーに次のものを持っています:
#define MY_C_API extern "C" __declspec(dllexport);
MY_C_API __declspec(dllexport) void __stdcall setLoggerPointer( void *fctPointer(LPCTSTR msg) );
MY_C_API __declspec(dllexport) bool __stdcall init();
そしてC++ソースでは:
//global variable
void *(*logger)(LPCTSTR msg);
void __stdcall setLoggerPointer( void *fctPointer(LPCTSTR msg) )
{
logger = fctPointer;
}
bool __stdcall init()
{
logger("WOOO");
return true; //I'm getting the AccessViolation right here
}
mfc100.dll内のatlsimpstr.hRelease()関数のinit()関数から戻ると、System.AccessViolationExceptionが発生します。
誰かが私が間違っていることを知っていますか?この種のことについて私が見たすべての質問は、アクセス違反なしで逆P / Invokeを実行する方法でしたが、それは私にとってはうまく機能しています。他の呼び出しから戻ったときに、そのセクションが台無しになっているようです。メモリはC#アプリケーションの一部と見なされるようになりました。