Большое Спасибо за этот плинтус! Я публикую нижеприведенное окончательное решение для всех, кто имеет дело с такими развлечениями, как этот! Пожалуйста, не стесняйтесь критиковать, так как я не закончил оптимизацию кода. Это может все еще быть окольным решением.
Сначала функции обратного вызова стали:
public delegate int ManagedCallbackFunction (IntPtr oInst, IntPtr oData);
public delegate int UnManagedCallbackFunction (void* inst, const void* data);
ManagedCallbackFunction^ m_callbackFn;
Большие реквизиты на этом. Это просто не будет работать, если вы попытаетесь привести из void * непосредственно к Object ^. Использование IntPtr и моего промежуточного обратного вызова:
int intermidiaryCallback(void * pInstance, const void * pData)
{
void* temp = (void*)pData;
return m_callbackFn->Invoke(IntPtr(pInstance), IntPtr(temp));
};
Наконец-то мы получили рабочую модель на стороне C # с некоторым массажем объектов:
public static int hReceiveTestMessage(IntPtr pInstance, IntPtr pData)
{
// provide object context for static member function
helloworld2 hw = (helloworld2)GCHandle.FromIntPtr(pInstance).Target;
if (hw == null || pData == null)
{
Console.WriteLine("hReceiveTestMessage received NULL data or instance pointer\n");
return 0;
}
// populate message with received data
IntPtr ip2 = GCHandle.ToIntPtr(GCHandle.Alloc(new DataPacketWrap(pData)));
DataPacketWrap dpw = (DataPacketWrap)GCHandle.FromIntPtr(ip2).Target;
uint retval = hw.m_testData.load_dataSets(ref dpw);
// display message contents
hw.displayTestData();
return 1;
}
Я упоминаю "массирование" объектов, потому что делегат не является специфическим для этой функции обратного вызова, и я не знаю, каким будет объект pData до времени выполнения (из POV делегатов). Из-за этой проблемы мне нужно проделать дополнительную работу с объектом pData. Мне пришлось перегрузить конструктор в моей оболочке, чтобы принять IntPtr. Код предоставляется для полной «ясности»:
DataPacketWrap (IntPtr dp)
{
DataPacket* pdp = (DataPacket*)(dp.ToPointer());
m_NativeDataPacket = pdp;
};