gpt4 book ai didi

C# 如何在结构中调用回调

转载 作者:行者123 更新时间:2023-11-30 18:31:27 25 4
gpt4 key购买 nike

我正在使用 3.party SDK,它由 .dll、.lib 和 .h 文件组成。我正在使用 .dll 来反对 PInvoke。以及用于查看函数名称和参数的 .h 文件。 (所以我没有使用 .lib 文件)。

SDK 相当复杂,因此制作 PInvoke 包装器已被证明是一项挑战。所有函数/结构/枚举都在 .h 文件中定义。

我正在将一个结构解析为非托管 C 代码,该结构包含 2 个委托(delegate),非托管 C 代码调用它们。

我正在用 C# 创建结构,并且两个委托(delegate)都在 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);

结构:回调接口(interface)

//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...
}

最佳答案

回调很可能是cdecl,但我对此比较怀疑:

[DllImport("myDll.dll", EntryPoint = "CallBackFunction", CallingConvention = CallingConvention.Cdecl)]
public static extern ERROR CallBackFunction(ref CallBackInterface callBack);

你试过这样吗(如果你不想在 C++ 中使用与 C# 不同的名称,那么 EntryPoint 是多余的,stdcall 是 DllImport 的默认调用约定,也是 DLL 导出的常用调用约定):

[DllImport("myDll.dll")]
public static extern ERROR CallBackFunction(ref CallBackInterface callBack);

关于C# 如何在结构中调用回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20147284/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com