从C#开始,我需要设置回调到C ++,其中使用回调接收的数据来自具有继承的结构(请参阅下面C ++部分中的提取代码)。
我相信编译器会崩溃C ++中的结构,因为它们不包含任何虚函数?因此,在C#中使用折叠数据类“CollapsedCallbackInfo”实际上适用于该特定数据类。但是在真正的问题中有很多不同的数据类和多层继承,有没有办法解决这个挑战? 我需要在委托定义中使用一些常用类型。
C#
回叫设置
[DllImport("NativeDLL", CallingConvention = CallingConvention.Cdecl)]
public static extern void SetupCallback(CallbackFunc callback);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void CallbackFunc(BaseCallbackInfo baseCallbackInfo);
C#数据类
[StructLayout(LayoutKind.Sequential)]
public class BaseCallbackInfo
{
public uint base_data;
};
[StructLayout(LayoutKind.Sequential)]
public class ConcreteCallbackInfo : BaseCallbackInfo
{
public uint concrete_data;
};
折叠数据类
[StructLayout(LayoutKind.Sequential)]
public class CollapsedCallbackInfo
{
public uint base_data;
public uint concrete_data;
};
说明回调设置的测试类
public class TestClass
{
public void RegisterCallback()
{
SetupCallback(new CallbackFunc(OnCallback));
}
public void OnCallback(BaseCallbackInfo baseCallbackInfo)
{
// In the real problem I know this cast is valid
ConcreteCallbackInfo ccbi = baseCallbackInfo as ConcreteCallbackInfo;
Debug.Log(ccbi.concrete_data)
}
}
C ++
数据类
struct BaseCallbackInfo
{
uint base_data;
};
struct ConcreteCallbackInfo : public BaseCallbackInfo
{
uint concrete_data;
};
C风格的回调定义和外部接口
typedef void( *CallbackFunc )( BaseCallbackInfo* in_pCallbackInfo );
extern "C"
__declspec(dllexport) void SetupCallback(CallbackFunc callback);
答案 0 :(得分:1)
只需定义几个相同的DllImports,例如
[DllImport("NativeDLL", EntryPoint="SetupCallback", CallingConvention = CallingConvention.Cdecl)]
public static extern void SetupCallback_Base(BaseCallbackFunc callback);
[DllImport("NativeDLL", EntryPoint="SetupCallback", CallingConvention = CallingConvention.Cdecl)]
public static extern void SetupCallback_Concrete1(Concrete1CallbackFunc callback);
[DllImport("NativeDLL", EntryPoint="SetupCallback", CallingConvention = CallingConvention.Cdecl)]
public static extern void SetupCallback_Concrete2(Concrete2CallbackFunc callback);
我建议你使用_stdcall而不是_cdecl。