Tuesday, April 07, 2009

Mission:  From C#, P/Invoke C++ with callbacks to C#

//-----------------------------------------------------------------------

// inside unmanaged C# code

//-----------------------------------------------------------------------

//-----------------------------------------------------------------------

//delegates - define a signatures for unmanaged c++ code to call

//-----------------------------------------------------------------------

public delegate void MessageReceivedDelegate(

   int param1,

   string messageString,

   int param3,

   int param4,

   int param5);

 

 

public delegate void ExceptionParsedDelegate(

  string exceptionMessage);

 

//-----------------------------------------------------------------------

// P/invoke mapping with pointers to delegated methods

//-----------------------------------------------------------------------

[DllImport("my.dll"

   , CallingConvention = CallingConvention.StdCall)]

public static extern void an_unmanaged_function(

   string aa,

    int bb,

    string cc,

    string dd,

    int ee,

    int ff,

    MessageReceivedDelegate call,

    ExceptionParsedDelegate exception);

 

 

//-----------------------------------------------------------------------

// perform P/invoke

//-----------------------------------------------------------------------

an_unmanaged_function(  

aa

,bb

,cc

,dd

,ee

,ff

,new MessageReceivedDelegate(OnMessageReceived)

,new ExceptionParsedDelegate(OnExceptionReceived));

 

//-----------------------------------------------------------------------

// delegated methods (called inside unmanaged c++ code)

//-----------------------------------------------------------------------

public void OnExceptionReceived(

   string exceptionMessage)

{

 

    //handle exceptionMessage

}

protected void OnMessageParsed(myMessage theMesssage)

{

    //handle theMesssage

}

 

//-----------------------------------------------------------------------

// inside unmanaged c++ code ("my.dll")

//-----------------------------------------------------------------------

 

//define c++ delegate signatures

 

typedef void (__stdcall *callbackDelegatePointer)(

       int param1,

       char message[2100],

       int param3,

       int param4,

       int param5);

typedef void (__stdcall *exceptionDelegatePointer)(

       char* exceptionMessage);

 

//allow p/invoke by delcaring method “extern "C"”

extern "C" __declspec(dllexport)

void __stdcall an_unmanaged_function(

       char *aa,

       int   bb,

       char *cc,

       char *dd,

       int   ee,

       int   ff,

       callbackDelegatePointer onMessageReceived,

       exceptionDelegatePointer onException)

 

//call delegates

onMessageReceived(param1, message, param3, param4, param5);

             

onException("Hello Exception");

 

 

 

 

Mission:  Show elapsed time on a WinfForm in C#

thanks to Mahesh Chand

original article:  http://www.c-sharpcorner.com/UploadFile/mahesh/WorkingwithTimerControlinCSharp11302005054911AM/WorkingwithTimerControlinCSharp.aspx

1) add stop & start buttons and a timer control on a web form

2) put code behind the buttons (below), that consumes the StopWatch class (below)

    public partial class Form1 : Form
    {
        static void Main()
        {
            Application.Run(new Form1());
        }
        public Form1()
        {
            InitializeComponent();
        }

        StopWatch stopWatch = new StopWatch();

        private void btnStart_Click(object sender, EventArgs e)
        {
            timer1.Enabled = true;
            stopWatch.Start();
        }

        private void btnStop_Click(object sender, EventArgs e)
        {
            timer1.Enabled = false;
            stopWatch.Stop();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            lblElapsedTime.Text = stopWatch.GetElapsedTimeString();
        }
    }

    public class StopWatch
    {

        private DateTime startTime;
        private DateTime stopTime;
        private DateTime currentTime;
        private bool running = false;


        public void Start()
        {
            this.startTime = DateTime.Now;
            this.running = true;
        }


        public void Stop()
        {
            this.stopTime = DateTime.Now;
            this.running = false;
        }


        // elaspsed time in milliseconds
        public string GetElapsedTimeString()
        {
            TimeSpan interval;

            if (!running)
                return ""; //interval = DateTime.Now - startTime;
            else
            {
                this.currentTime = DateTime.Now;
                interval = currentTime - startTime;
            }

            int days = interval.Days;
            double hours = interval.Hours;
            double mins = interval.Minutes;
            double secs = interval.Seconds;
            string x = "";
            if (days != 0)
            {
                x += days.ToString() + ":";
            }
            if (hours != 0)
            {
                x += hours.ToString("00") + ":";
            }
            x += mins.ToString("00") + ":";
            x += secs.ToString("00");

            return x;
        }
        public double GetElapsedMilliseconds()
        {
            TimeSpan interval;

            if (running)
                interval = DateTime.Now - startTime;
            else
                interval = stopTime - startTime;

            return interval.TotalMilliseconds;
        }


        // elaspsed time in seconds
        public double GetElapsedTimeSecs()
        {
            TimeSpan interval;

            if (running)
                interval = DateTime.Now - startTime;
            else
                interval = stopTime - startTime;

            return interval.TotalSeconds;
        }
    }