我正在使用由.dll,.lib和.h文件組成的3. party SDK。我正在使用.dll來對付PInvoke。和.h文件來查看函數名稱和參數。 (所以我沒有使用.lib文件)。C#如何在結構中調用回調
SDK相當複雜,所以使得PInvoke包裝被證明是一個挑戰。所有的函數/結構體/枚舉都在.h文件中定義。
我解析一個結構到非託管C代碼,並且該結構包含2個委託,非託管C代碼調用。
我在C#中創建結構,並且這兩個代表都在C#中設置。
當我調用它時,我得到'System.AccessViolationException'。
使用
//C#
private CallBackInterface callBack;
public void MyMethod()
{
callBack = new CallBackInterface();
callBack.event1 = new CallBackInterface.event1_delegate(event1_Handler);
callBack.event2 = new CallBackInterface.event2_delegate(event2_Handler);
CallBackFunction(ref callBack); //Throws a 'System.AccessViolationException'
}
public int event1_Handler(IntPtr Inst, uint type, uint timeMs)
{
Console.WriteLine("Got a callback on event 1!");
return 0;
}
public int event2_Handler(IntPtr Inst, out LH_BOOL Continue)
{
Console.WriteLine("Got a callback on event 2!");
Continue = LH_BOOL.TRUE;
return 0;
}
功能:callbackFunction參數
//C
ERROR CallBackFunction(CallBackInterface * callBack);
//C#
[DllImport("myDll.dll", EntryPoint = "CallBackFunction", CallingConvention = CallingConvention.Cdecl)]
public static extern ERROR CallBackFunction(ref CallBackInterface callBack);
結構:的callbackInterface
//C
typedef unsigned long LH_TIME;
typedef struct CallBackInterface_S{
int (*event1) (void* inst, unsigned long type, LH_TIME timeMs);
int (*event2) (void* inst, LH_BOOL* Continue); //continue should be set to tell the unmanaged c code if it should continue or stop.
} CallBackInterface;
//C#
[StructLayout(LayoutKind.Sequential)]
public struct CallBackInterface
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int event1_delegate(IntPtr inst, uint type, uint timeMs);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int event2_delegate(IntPtr inst, out LH_BOOL Continue);
public event1_delegate event1;
public event2_delegate event2;
}
枚舉:LH_BOOL
//C Enum: LH_BOOL
typedef enum LH_BOOL_E {
FALSE= 0,
TRUE = 1,
} LH_BOOL;
//C# Enum: LH_BOOL
public enum LH_BOOL
{
FALSE= 0,
TRUE = 1,
}
枚舉:錯誤
//C Enum: ERROR
typedef enum ERROR_E {
OK = 0, //Everything is ok
E_ARG = 1, //Error in the Arguments
E_DATA = 2 //Data error
//And more...
} ERROR;
//C# Enum: ERROR
public enum ERROR
{
OK = 0, //Everything is ok
E_ARG = 1, //Error in the Arguments
E_DATA = 2 //Data error
//And more...
}
你知道最初的調用是否發生異常,或者發生了其中一次回調?如果是後者,你知道它是哪個回調嗎? –
我沒有訪問C代碼的權限,我只能訪問.dlls。所以我不知道什麼時候在C代碼中發生問題。但我期望它是當試圖調用我的C#函數。 –
我現在有同樣的問題。真的希望有人知道了! – koby