[openamq-dev] MS C# using Windows dll with exports.

Bo Kohut bo.kohut at gmail.com
Fri Mar 28 05:34:33 CET 2008


Martin Sustrik,

As requested I have joined the fun to benefit others in my quest as
this being my first post.  This code is provided AS IS with NO
guarantee, use as you see fit.

Would you happen to have released the build scripts/code for the dlls
with exports as posted on the wiki
(http://wiki.openamq.org/package:win32-builds).  I would hope to
obtain this info and then build on windows producing debug files if
possible.  Below you will find what I have started in c# using
openamq's dlls with exports functions from within VS 2005 c# (managed
code calling unmanaged code through pinvoke).  I used the single
threaded debug version within this code.

A question relates to my options to view tracing while running if I am
not able to obtain the dll builds for modifying.  I am compiling an
exe and simply running it from command line, not from within the IDE.
I would like to use something such as sysinternals debugview
(capturing kernel debugoutput) but what tools do you use (freeware i
hope) to view the trace output?

As we discussed via other channels I am determined to use your own
client code, while this is not pure .net as rabbitmq offers, I am
reassured it works for your server offering since it is what you
yourself use.

For those trying to run the code below I DO NOT have the connection
create or destroy working.  As some may know the secret is in
translating the variables, both headers and function calls.  The only
working functions are "icl_system_initialise", "icl_system_terminate",
"amq_client_connection_auth_plain", "icl_longstr_destroy_".  You will
see the that "amq_client_connection_auth_plain" is confirmed working
by using the PtrToStructure call and then the PtrToString call and
console.writeline-ing the string.  I commented out the connection
create and destroy as they are not yet working, might be the
strc_amq_client_connection_t translation....  More time with this
tomorrow...

Code is below, did my best to Ctrl C Ctrl V

**************************************************************************************************************************

using System;
using System.Runtime.InteropServices;
using System.Text;

namespace wrappertest
{
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct strc_icl_longstr_t
    {
        public int object_tag;
        public int cur_size;
        public int max_size;
        public IntPtr pbData;
    };

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct strc_icl_shortstr_t
    {
        public char[] arrData;
    };

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct strc_amq_client_connection_t
    {
        public byte object_tag;                     //  Object validity marker
        public IntPtr thread;                       //  Thread for
this connection (Structure NOT defined here)
        public IntPtr method_queue;                 //  Replies from
protocol agent (Structure NOT defined here)
        public UInt16 channel_nbr;                  //  Top channel
opened so far
        public bool silent;                         //  Don't print errors
        public bool alive;                          //  Connection is alive?
        public bool interrupt;                      //  Application
was interrupted?
        public bool shutdown;                       //  We were shutdown
        public int timeout;                         //  Connection
timeout, msecs
        public IntPtr error_text;                   //  Last error cause
        public byte version_major;                  //  protocol major version
        public byte version_minor;                  //  protocol major version
        public UInt16 channel_max;                  //  proposed
maximum channels
        public int frame_max;                       //  proposed
maximum frame size
        public UInt16 heartbeat;                    //  desired heartbeat delay
        strc_icl_shortstr_t known_hosts;            //  list of known hosts
        strc_icl_shortstr_t host;                   //  server to connect to
        public UInt16 reply_code;                   //  reply code from server
        strc_icl_shortstr_t reply_text;             //  localised reply text
        public UInt16 class_id;                     //  failing method class
        public UInt16 method_id;                    //  failing method ID
        strc_icl_shortstr_t server_host;
        strc_icl_shortstr_t server_name;
        strc_icl_shortstr_t server_product;         //  Reported by server
        strc_icl_shortstr_t server_version;
        strc_icl_shortstr_t server_platform;
        strc_icl_shortstr_t server_copyright;
        strc_icl_shortstr_t server_information;
        strc_icl_shortstr_t server_instance;
    };

    class wrapperclass
    {
        //********************************************************************************

        [DllImport("oamqclistd.dll", EntryPoint =
"icl_system_initialise", ExactSpelling = true, CallingConvention =
CallingConvention.Cdecl)]
        static public extern void fn_icl_system_initialise(int argc,
ref IntPtr argv);

        public static void AmqInitialise(int ArgCount, ref IntPtr Args)
        {
            fn_icl_system_initialise(ArgCount, ref Args);
            return;
        }

        //********************************************************************************

        [DllImport("oamqclistd.dll", EntryPoint =
"icl_system_terminate", ExactSpelling = true, CallingConvention =
CallingConvention.Cdecl)]
        static public extern void fn_icl_system_terminate();

        public static void AmqTerminate()
        {
            fn_icl_system_terminate();
            return;
        }

        //********************************************************************************

        [DllImport("oamqclistd.dll", EntryPoint =
"amq_client_connection_auth_plain", ExactSpelling = true,
CallingConvention = CallingConvention.Cdecl)]
        static public extern IntPtr
fn_amq_client_connection_auth_plain(string pszUserName, string
pszPassword);

        private static IntPtr ptrAuthData = IntPtr.Zero;

        public static strc_icl_longstr_t AmqAuthPlain(string
sShapeFile, string sAccess)
        {
            ptrAuthData =
fn_amq_client_connection_auth_plain(sShapeFile, sAccess);
            return
(strc_icl_longstr_t)Marshal.PtrToStructure(ptrAuthData,
typeof(strc_icl_longstr_t));
        }

        //********************************************************************************

        [DllImport("oamqclistd.dll", EntryPoint =
"icl_longstr_destroy_", ExactSpelling = true, CallingConvention =
CallingConvention.Cdecl)]
        static public extern void fn_icl_longstr_destroy(ref IntPtr
ptr_strc_icl_longstr_t);

        public static void LongStrDestroy(ref IntPtr pStructLongStr)
        {
            fn_icl_longstr_destroy(ref pStructLongStr);
            return;
        }

        //********************************************************************************

        [DllImport("oamqclistd.dll", EntryPoint =
"amq_client_connection_new_", ExactSpelling = true, CallingConvention
= CallingConvention.Cdecl)]
        static public extern IntPtr
fn_amq_client_connection_new(string pszHost, string pszVirtualHost,
ref IntPtr ptr_strc_icl_longstr_t, byte[] pbzInstance, int piTrace,
int piTimeout);

        private static IntPtr ptrClientConn = IntPtr.Zero;

        public static strc_amq_client_connection_t
AmqClientConnectionCreate(string sHost, string sVirtualHost, ref
IntPtr pStructAuthData, string sInstance, int iTrace, int iTimeout)
        {
            IntPtr ptrClientConn = fn_amq_client_connection_new(sHost,
sVirtualHost, ref pStructAuthData, Encoding.ASCII.GetBytes(sInstance +
"\0"), iTrace, iTimeout);
            return
(strc_amq_client_connection_t)Marshal.PtrToStructure(ptrClientConn,
typeof(strc_amq_client_connection_t));
        }

        //********************************************************************************

        [DllImport("oamqclistd.dll", EntryPoint =
"amq_client_connection_destroy_", ExactSpelling = true,
CallingConvention = CallingConvention.Cdecl)]
        static public extern void fn_amq_client_connection_destroy(ref
IntPtr ptr_strc_amq_client_connection_t);

        public static void AmqClientConnectionDestroy(ref IntPtr
ptrStructClientConn)
        {
            fn_amq_client_connection_destroy(ref ptrStructClientConn);
            return;
        }

        //********************************************************************************

        static void Main(string[] args)
        {
            Console.WriteLine("");
            Console.WriteLine("Attempting AmqInitialise");
            IntPtr pArgs = IntPtr.Zero;
            AmqInitialise(0, ref pArgs);
            Console.WriteLine("Succeeded AmqInitialise");

            strc_icl_longstr_t strcAuthData;

            Console.WriteLine("");
            Console.WriteLine("Attempting AmqAuthPlain");
            strcAuthData = AmqAuthPlain("guest", "guest");
            Console.WriteLine("Succeeded AmqAuthPlain");

            Console.WriteLine("Object: " + strcAuthData.object_tag);
            Console.WriteLine("Cur Size: " + strcAuthData.cur_size);
            Console.WriteLine("Max Size: " + strcAuthData.max_size);
            string strdata =
Marshal.PtrToStringAnsi(strcAuthData.pbData, strcAuthData.cur_size);
            Console.WriteLine("*Data: " + strdata);

            //Console.WriteLine("");
            //Console.WriteLine("Attempting AmqClientConnectionCreate");
            //strc_amq_client_connection_t strcConnection;
            //strcConnection = AmqClientConnectionCreate("localhost",
"/", ref ptrAuthData, "amq_client", 0, 30000);
            //Console.WriteLine("Succeeded AmqClientConnectionCreate");

            //if (strcConnection.alive)
            // //if (strcConnection.error_text = "no error")
            //{
            //    Console.WriteLine("Connected to server.");

                //a_sessions[the_index] = amq_client_session_new(connection);
                //a_connections[the_index] = connection;

                //amq_client_session_destroy (&a_sessions [the_index]);

            //    Console.WriteLine("");
            //    Console.WriteLine("Attempting AmqClientConnectionDestroy");
            //    AmqClientConnectionDestroy(ref ptrClientConn);
            //    Console.WriteLine("Succeeded AmqClientConnectionDestroy");
            //}
            //else
            //{
            //    Console.WriteLine("Could not connect to server.");
            //}

            Console.WriteLine("");
            Console.WriteLine("Attempting LongStrDestroy");
            LongStrDestroy(ref ptrAuthData);
            Console.WriteLine("Succeeded LongStrDestroy");

            Console.WriteLine("");
            Console.WriteLine("Attempting AmqTerminate");
            AmqTerminate();
            Console.WriteLine("Succeeded AmqTerminate");
        }
    }
}

-- 
Bo Kohut


More information about the openamq-dev mailing list