Archives

Anticipation

    No dates present

AppDomains and unmanaged callbacks, redux

Quite a while back, I posted an article about getting native callbacks to work across AppDomains. Since then, I’ve gotten quite a few comments with varying levels of confusion, and seen a few implementations that appear to have missed something along the way. So I thought it’d be a good idea to post a clarification.

Fundamentally, there are just a few things that you need to remember:

  • You cannot access managed objects (including GCHandles and gcroots) outside of the AppDomain in which they were created.
  • Each thread which has executed managed code has a “history” linking it to a particular AppDomain. If a thread has never executed managed code before, though, then the first time it tries it will be assumed to be in the first AppDomain.
  • Delegates contain information about which AppDomain they should be executed in, so they can “cross the line” when an otherwise pure native thread has no idea which AppDomain it should be using.
  • Managed delegates can be turned into native function pointers via the Marshal::GetFunctionPointerForDelegate method.
  • If you create a function pointer from a delegate, you must keep the delegate alive (by keeping a reference to it) for as long as the native pointer exists.
  • Native functions can only have native types as parameters (but they don’t have to just be primitive types). (Actually, there are some limited exceptions to this, which I cover below.)

So, here’s a few example scenarios, to get your head around the ideas. Note that none of these care whether you’re crossing AppDomain boundaries or not (they’re cross-AppDomain-safe, but can be used within the same AppDomain too), so they can also serve as good examples for regular interop scenarios as well.
Continue reading AppDomains and unmanaged callbacks, redux

Unmanaged callbacks across AppDomains

In one of the projects I’m working on I hit a fairly nasty problem involving (as might be obvious from the title) both AppDomains and unmanaged code calling back into managed code. But first, a little background.

It all started with an unmanaged C++ class library. We’ve been using it for a while from other unmanaged C++ applications, but since we’ve been writing most new applications in C#.NET, the time had come to bring the library (kicking and screaming) into the .NET world. Naturally, the way forward was to write a compatibility layer in C++.NET, thereby taking advantage of its IJW framework (which makes C++ the best .NET language to use to interface with native code). (.NET 2.0, of course. Don’t even get me started about some of the problems interfacing native & managed code in 1.x.) Continue reading Unmanaged callbacks across AppDomains