[zeromq-dev] P/Invoke-based CLR access to zeroMQ

Barak Amar barak.amar at gmail.com
Thu Feb 19 12:00:18 CET 2009


Hi Dirk,
I've wrapped the C implementation withe P/Invoke.  I didn't test it yet on a
working environment and as far as I know in order to make it work on Mono
you will have to add a XML file for mapping the DLL name to shared library
name.

---- the code --

using System;
using System.Runtime.InteropServices;

namespace zmq
{

    public class Dnzmq : IDisposable
    {
        private IntPtr zmq_;

        public const int SCOPE_LOCAL = 0;
        public const int SCOPE_GLOBAL = 1;

        public Dnzmq()
        {
            zmq_ = IntPtr.Zero;
        }

        public Dnzmq(string host)
        {
            Open(host);
        }

        public void Open(string host)
        {
            zmq_ = czmq_create(host);
        }

        public bool IsOpen { get { return zmq_ == IntPtr.Zero; } }

        public int CreateExchange(string exchange, int scope, string nic)
        {
            if (zmq_ == IntPtr.Zero)
                throw new NullReferenceException("queue must be
initialized");
            return czmq_create_exchange(zmq_, exchange, scope, nic);
        }

        public int CreateQueue(string queue, int scope, string nic, Int64
hwm, Int64 lwm, Int64 swapSize)
        {
            if (zmq_ == IntPtr.Zero)
                throw new NullReferenceException("queue must be
initialized");
            return czmq_create_queue(zmq_, queue, scope, nic, hwm, lwm,
swapSize);
        }

        public void Bind(string exchange, string queue, string exchangeArgs,
string queueArgs)
        {
            if (zmq_ == IntPtr.Zero)
                throw new NullReferenceException("queue must be
initialized");
            czmq_bind(zmq_, exchange, queue, exchangeArgs, queueArgs);
        }

        public void Send(int eid, byte[] data)
        {
            if (zmq_ == IntPtr.Zero)
                throw new NullReferenceException("queue must be
initialized");
            IntPtr ptr = Marshal.AllocHGlobal(data.Length);
            Marshal.Copy(data, 0, ptr, data.Length);
            czmq_send(zmq_, eid, ptr, Convert.ToUInt32(data.Length),
Marshal.FreeHGlobal);
        }

        public byte[] Receive()
        {
            if (zmq_ == IntPtr.Zero)
                throw new NullReferenceException("queue must be
initialized");
            IntPtr data;
            UInt32 dataSize;
            FreeMsgData freeFunc;
            czmq_receive (zmq_, out data, out dataSize, out freeFunc);

            if (data == IntPtr.Zero)
                return new byte[0];

            byte[] msg = new byte[dataSize];
            Marshal.Copy(data, msg, 0, Convert.ToInt32(dataSize));
            if (freeFunc != null)
                freeFunc(data);
            return msg;
        }

        private delegate void FreeMsgData(IntPtr ptr);

        public void Close()
        {
            if (zmq_ != IntPtr.Zero)
            {
                czmq_destroy(zmq_);
                zmq_ = IntPtr.Zero;
            }
        }

        #region IDisposable Members

        public void Dispose()
        {
            Close();
        }

        #endregion

        #region C API

        [DllImport("libczmq.dll", CharSet=CharSet.Ansi)]
        static extern IntPtr czmq_create(string host);

        [DllImport("libczmq.dll")]
        static extern void czmq_destroy(IntPtr zmq);

        [DllImport("libczmq.dll", CharSet=CharSet.Ansi)]
        static extern int czmq_create_exchange (IntPtr zmq, string exchange,
int scope, string nic);

        [DllImport("libczmq.dll", CharSet=CharSet.Ansi)]
        static extern int czmq_create_queue (IntPtr zmq, string queue, int
scope, string nic,
            Int64 hwm, Int64 lwm, Int64 swapSize);

        [DllImport("libczmq.dll", CharSet=CharSet.Ansi)]
        static extern void czmq_bind (IntPtr zmq, string exchange, string
queue,
            string exchangeArgs, string queueArgs);

        [DllImport("libczmq.dll")]
        static extern void czmq_send (IntPtr zmq, int eid, IntPtr data_,
UInt32 size, FreeMsgData ffn);

        [DllImport("libczmq.dll")]
        static extern void czmq_receive (IntPtr zmq, [Out] out IntPtr data,
[Out] out UInt32 size, [Out] out FreeMsgData ffn);

        #endregion
    }
}

-- Barak

On Thu, Feb 19, 2009 at 10:44 AM, Dirk O. Siebnich <dok at dok-net.net> wrote:

> Hi Barak,
>
> Martin Sustrik let me know that you have / are working on a patch to 0MQ
> that replaces the MS .NET only solution using managed C++ with something
> that might work on Mono. If you could share this with me for evaluation,
> I would be quite happy?
>
> Thanks in advance,
> best regards,
> Dirk
>
> _______________________________________________
> zeromq-dev mailing list
> zeromq-dev at lists.zeromq.org
> http://lists.zeromq.org/mailman/listinfo/zeromq-dev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.zeromq.org/pipermail/zeromq-dev/attachments/20090219/af9afac2/attachment.html>


More information about the zeromq-dev mailing list