Calling Managed code from Native Code.

In today’s Windows CE 5.0 online chat (which was pretty busy from start to finish) one of the questions that came up was whether Windows CE supports the ability to call managed code from native code (kinda like a reverse P/Invoke).

There is limited Com Callable Wrappers (CCW) support in CF 2.0.  However, there is no registration or activation support in CF 2.0.

What this means is that a managed application can pass managed interfaces to native code, and the native code can treat these interfaces as COM Interface Pointers to make calls back into the managed code.  Additionally, CF 2.0 supports passing managed delegates to native code as function pointers which native code can used to call back into managed code.  However, there is no support for a purely native app to call into managed code.  All pointers need to be passed from managed code to native code before any calls can be made back into managed code.

More information about Com Callable Wrappers can be found on MSDN

So, I have a question for you… if you’re writing applications for Windows CE Embedded devices, or Pocket PC/Smartphone devices, are you using Win32/MFC/ATL, or C#/VB – and why did you choose to use that programming model ?

– Mike

Comments (4)

  1. Daniel Moth says:

    It is probably useful to point out that the question of calling managed from native code comes up a lot in the newsgroup. Although nobody is pleased with the negative reply, some have been satisfied with the workaround of inter-process communication. I.e. have the managed and unmanaged sides run in separate processes and talk to each other via standard IPC mechanisms. All the IPC options (with plenty of links) are summarised here:

    (and when one day the nice CF team allows us to host the runtime on WinCE like we can on the PC, life will be goodness 🙂

  2. Mike says:

    Thanks for the link Daniel – very helpful !

    – Mike

  3. I’ve had the most success using Point to Point message queues (CE’s msgqueue functions, not to be confused with msmq — there is no equivelent in .net). Setting up a listener in CF can be done in a few lines; then, just drop some bytes in the queue, and it shows up on the CF side of the world (which is monitoring the queue via a blocking wait handle).

    As a method for invoking CF code, there are several approaches worth considering…

    1. You can just signal events–native code drops an enum/int value (or string, if you like) into the queue. CF pulls them out, and takes action via a switch statement. For more general eventing, have your lister publish events so that other CF code can subscribe to the events.

    2. Native can serialize parameters and pass them through the queue. XML is convienient (and easy to follow in the debugger), and often a lot simpler than tryint to [Layout] structs for interop… especially since interop marshalling isn’t well supported in CF 1.0.

    3. Sometimes, what you really want is to make a native call to CF and get return values. Combine #1 & #2 (fire a signal, optionally with params) and then have the CF respond by pinvoking the result back to native (the params passed can be used to negotiate how the result is returned).

    4. Bonus: Combined with reflection, you can roll a generalized dynamic calling scheme–from native, create an xml struct that defines a methodname followed by params, and have the CF side deserialize it, look up the method using reflection, then invoke it. Spiffy, though not necessarily all that useful for most practical applications.