how to use "inproc" for connecting C# and C++ (how to share context?)

921 Views Asked by At

I want to connect c++ and c# side of my application using "inproc" binding. To do that I need to share context somehow, because both c# and c++ parts should use the same context. How can I do that? I'm using official c++ and c# bindings.

I.e. on c# side i need ZeroMQ.ZmqContext.

And on c++ side i need zmq::context_t.

And both instances should point to the same context so I can use "inproc".

1

There are 1 best solutions below

0
On

ZContext has a public IntPtr ContextPtr { get; } field.

Albiet a hacky approach - using reflection seems to be the only way to access that field currently. Unless API is added to the C# wrappers to allow initialization from a raw pointer (and similarly add ownership API), this seems like the only route.

Something like this could be done:


using ZeroMQ;

public static class ZContextExtension
{
    public static void SetContextPtr(this ZContext context, IntPtr ptr)
    {
        PropertyInfo propertyInfo = typeof(ZContext).GetProperty("ContextPtr");
        if (propertyInfo == null) return;
        propertyInfo.SetValue(context, ptr);
    }
}

void DoStuffWithSharedContext(IntPtr ctx) {

    ZContext context = ZContext.Create();

    // Terminate to dealloc the current zmq_ctx
    context.Terminate(out ZError initialContextCreateError);

    // Reflect and assign
    context.SetContextPtr(ctx);

    // ... do whatever you need to with the shared context ...

    // Set the ptr to IntPtr.zero before Disposal
    // Note: This can be skipped if the context is expected to be managed/dealloc'd by C#
    context.SetContextPtr(IntPtr.zero);
}

Getting and passing the IntPtr to the Context is up to you. There's several ways to do that:

  • Pass in through another bridging library
  • Pass in out-of-band through a file
  • Pass in through a separate ZMQ connection (IPC, loopback TCP, etc)
  • as many ways to get a simple int passed around as you can think of...

As a side note: It would be neat to have context initialization from raw pointers (with ownership API) in ZeroMQ wrappers. It would go a long way to allowing a lot of inter-process messaging between different language runtimes.

Hopefully the ZMQ team implements this!