Из C # мне нужно настроить обратный вызов в C ++, где данные, полученные в результате обратного вызова, происходят из структур с наследованием (см. Дистиллированный код ниже в разделе C ++).
Я считаю, что структуры в C ++ свернуты компилятором, потому что они не содержат никаких виртуальных функций? Поэтому использование свернутого класса данных CollapsedCallbackInfo в C # действительно работает для этого конкретного класса данных. Но если в реальной проблеме много разных классов данных с несколькими уровнями наследования, есть ли способ решить эту проблему?
Мне нужен какой-то общий тип для использования в моем определении делегата.
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);