You got your C# in my C++!

I’ve been writing apps in mostly C# for several years now.  Of course I’ve also been doing drivers and kernel work in C or C++, and that has only improved my ability to write, debug and understand managed code in ways that pure managed developers will never really get.  Hell, I pretty much believe that if your managed code doesn’t require allowing unsafe code then it could probably be done better.


Well for a few months now I’ve been neck-deep in a C++ application.  It was started using MFC, which tends to give me a rash just by saying the letters, but it was a customer decision not mine.  At any rate, I was doing some work with a RAS class where I needed any number of consumers to be able to be notified of any changes in the RAS dial status (dialing, connecting, authenticating, etc.).


Imagine a C# class for RAS that will expose events for when the dial staus changes.  THe first thing you’d need is a delegate, right?


In C# you’d have this (assuming DialStatus is an enum):



delegate void DialStatusChange(DialStatus dialStatus);


Well the c++ I wrote (without even thinking about C#) looked eerily familiar:



typedef void(*DIAL_STATUS_DELEGATE)(DialStatus newStatus);


In C# you’d use the += or -= operators for adding an event handler to a classes event, so we get spoiled.  In VB, you call AddHandler with the event name and then the address of the handler.  Well my C++ had a private vector of function pointers (which the CF maintains internally):



std::vector <DIAL_STATUS_DELEGATE> ConnectionManager::m_statusCallbackList;


And then I added methods for adding and removing handlers to the class:



 void ConnectionManager::StatusAddHandler(DIAL_STATUS_DELEGATE callback)
 {
   m_statusCallbackList.push_back(callback);
 }
 
 void ConnectionManager::StatusRemoveHandler(DIAL_STATUS_DELEGATE callback)
 {
   std::vector<DIAL_STATUS_DELEGATE>::iterator iterator;
 
   for(iterator = m_statusCallbackList.begin() ; iterator != m_statusCallbackList.end() ; iterator++)
   {
     if((*iterator) == callback)
     {
        m_statusCallbackList.erase(iterator);
        break;
     }
   }
 }


And how about usage?  In C#, our event-exposing class would have a defined event:



 event DialStatusChange OnStatusChange;


and then when we want to raise the event (assume it’s multicast) from our app, we’d do something like this:



 if (OnStatusChange != null)
 {
     foreach (DialStatusChange dsc in OnStatusChange.GetInvocationList())
     {
         dsc(newStatus);
     }
 }


Well my C++ didn’t need the event declaration, but raising the “event” (which is simply calling a function pointer callback) looked like this:



 std::vector<DIAL_STATUS_DELEGATE>::iterator iterator;
 
 recheck2:
 for(iterator = m_statusCallbackList.begin() ; iterator != m_statusCallbackList.end() ; iterator++)
 {
   if(IsBadCodePtr((FARPROC)(*iterator)))
   {
      // invalid callback found (someone hooked us then died without unhooking)
      m_statusCallbackList.erase(iterator);
      goto recheck2;
   }
      (*iterator)(status);
 }


Now this was just off the top of my head, so maybe there are improvements that could be made, but it kind of surprised me how I’d taken the concepts I really learned in C# and translated them back to my C++ code.  So yes, writing C# can make you a better C++ developer.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s