0

Is there a simple example of how to pass messages from unsafe callback to managed code?

I have a proprietary dll which receives some messages packed in structs and all is coming to a callback function.

The example of usage is as follows but it calls unsafe code too. I want to pass the messages into my application which is all managed code.

*P.S. I have no experience in interop or unsafe code. I used to develop in C++ 8 yrs ago but remember very little from that nightmarish times :)

P.P.S. The application is loaded as hell, the original devs claim it processes 2mil messages per sec.. I need a most efficient solution.*

static unsafe int OnCoreCallback(IntPtr pSys, IntPtr pMsg)
{
  // Alias structure pointers to the pointers passed in.
  CoreSystem* pCoreSys = (CoreSystem*)pSys;
  CoreMessage* pCoreMsg = (CoreMessage*)pMsg;

  // message handler function.
  if (pCoreMsg->MessageType == Core.MSG_STATUS)
    OnCoreStatus(pCoreSys, pCoreMsg);

  // Continue running
  return (int)Core.CALLBACKRETURN_CONTINUE;
}

Thank you.

  • What will the managed code be doing with the messages? What kind of data are the messages? Strings? Or pointers that will be passed back into unmanaged/unsafe code? The answer depends completely on things like this. – snarf Mar 20 '10 at 00:09
  • I see.. the messages will not return to unmanaged code for sure... What I did so far - I added bit of unmanaged code from API samples into my *working WPF app and I wrap each message data into a struct which I already use in WPF and push it back to a window... The problem is that when I call this.Dispatcher.BeginInvoke(new Action(() => { OnDataReceived(data); })... I never get into OnDataReceived method. I tried to set breakpoint in it and it never hit too.... I am now stuck... Note MyStruct and dispatcher action and OnDataReceived - all is working when I call it from managed threads –  Mar 21 '10 at 18:55
  • P.S. MyStruct is small 32 bit struct - all int, uint, long.. No ref types at all. not even string. –  Mar 21 '10 at 18:57

1 Answers1

0

You can use Marshal class to deal with interop code.

example:

C:
void someFunction(int msgId, void* funcCallback)
{
   //do something
   funcCallback(msgId); //assuming that  function signature is "void func(int)"
}

C#
[DllImport("yourDllname.dll")]
static extern someFunction(int msgId, IntPtr funcCallbackPtr);

public delegate FunctionCallback(int msgId);
public FunctionCallback functionCallback;

public void SomeFunction(int msgId, out FunctionCallback functionCallback)
{
   IntPtr callbackPtr;
   someFunction(msgId, callbackPtr);

   functionCallback = Marshal.DelegateToPointer(callbackPtr);
}

you can call as:
SomeFunction(0, (msgIdx) => Console.WriteLine("messageProcessed"));

I hope I did it right. I did not try to compile it :)

dajuric
  • 2,373
  • 2
  • 20
  • 43