January 14, 2009 | Comments Off
I have been a big fan of the Trolltech Qt Framework for a number of years. It is a fantastic way to build high quality cross-platform desktop applications in C++. For the past six years it seems like every project I work on has included a rich desktop GUI application of some sort. Each time this need would arise I would start the process of selling the idea of using the Qt Framework for the project. The biggest hurdle was always the per-developer cost for the commercial license of the framework. I would hear things like
Just use MFC. It’s free and we don’t really see a need for the application to be cross-platform anyway.
or sometimes I would hear
Use the GPL version of Qt and just keep it under the radar until we are sure the application will be released to our customers.
It was always frustrating to try and make the case that Qt was a better solution than MFC for UI, was more comprehensive for general development than other frameworks, and that it was worth planning for the possiblity of releasing the applications for Linux or Mac as well as Windows. In the end each project did adopt the Qt Framework, but it really was a distraction to try and justify the use.
Thankfully with the purchase of Trolltech by Nokia we are seeing a change in the licensing terms for the Qt Framework. Starting with the 4.5 release it looks like the framework will be placed under the LGPL license making it much easier to adopt as part of commercial development efforts.
Here are a couple links that discuss the development further:
and you can read the news directly from Nokia on the Qt Licensing Terms page.
This new development on the licensing front and the recent inclusion of WebKit into the Qt Framework make me very optimistic about a long and prosperous future for developers who know the Qt Framework! Thank you Nokia!
July 15, 2008 | Comments Off
A few years ago I was working at a company where we built applications using Visual Studio 6 and MFC. The applications had been around for about 10-12 years, and were all showing their age. Customers were beginning to request updated user interface features like they were seeing in modern Microsoft products such as Office and Internet Explorer. Sadly, we could not deliver these user interface enhancements easily because MFC was not getting any attention from Microsoft.
In late 2002 Microsoft was pushing the .NET Framework, C# and WinForms as the heir apparent for Win32, C++ and MFC. Converting a decade of legacy C++ MFC code to .NET and WinForms just wasn’t an option. We all felt like Microsoft had just abandoned us for greener pastures.
Our solution at the time was to start a long difficult process of moving away from MFC toward a cross-platform class library built by Trolltech, called Qt. In many respects this turned out to be a good decision since it meant we could begin to seriously consider offering our applications on Windows, Linux and the Mac instead of just on Windows. Still, it felt like Microsoft had hung us out to dry.
The WinForms classes just were not rich enough to build complex desktop applications at the time. Many of the conveniences we had come to rely upon from the MFC class libraries were missing and it would have been up to us to roll our own alternatives had we gone down the WinForms route. I think Microsoft was too focused on building web applications to devote sufficient resources to WinForms.
Here we are six years later and Microsoft has announced that they are providing a MFC Feature Pack for Visual C++ 2008 that will add significantly to the capabilities of the MFC class libraries. I can hear MFC development teams all across the Internet celebrating this change in stance from Microsoft.
Here are a couple links to information from Microsoft on the topic:
Couple MFC with a good third-party widget library like the toolkit offered by CodeJock Software and you have everything necessary to build some awesome new desktop applications.
Long Live MFC!
May 22, 2008 | Comments Off
One of the projects I work on makes use of the Win32 asynchronous I/O model for managing network traffic between a Windows Service and a custom-built network device.
One of the key Win32 APIs we use is called GetQueuedCompletionStatus. This API provides access to an I/O completion port that is managed by a separate operating system thread.
When dealing with this API and Windows asynchronous I/O in general it helps to think about the model as being supported by a separate workpool thread. This API gives the caller a way to synchronize with the operations of that workpool thread (or threads).
The prototype for this API is as follows:
BOOL GetQueuedCompletionStatus( HANDLE CompletionPort, LPDWORD lpNumberofBytes, PULONG_PTR lpCompletionKey, LPOVERLAPED* lpOverlapped, DWORD dwMilliseconds);
At first glance the API may not seem too complex. There are 5 parameters and a boolean return type. Some of the parameters are easy to figure out just be looking at their names. Others are less clear. You could speculate that the returned boolean is an indicator of whether or not the operation was successful or not. It is easy to be lulled into a false sense of understanding by reading through the first few paragraphs of the MSDN documentation on this API.
It actually turns out that this API is very complex (perhaps too complex?), and careful study of the MSDN documentation is required if you wish to handle all of the possible conditions when this API returns. Pay careful attention to the section in the documentation that discusses Return Values and Remarks.
My favorite gem from the return values section (and the one I recently missed when using this API) is:
If a socket handle associated with a completion port is closed, GetQueuedCompletionStatus returns ERROR_SUCCESS, with *lpOverlaped non-NULL and lpNumberOfBytes equal to zero.
In other words, when the socket is closed (possibly because the peer closed it) you will get what appears to be a successful I/O completion. This does not represent what most would consider a successful return, and if you have not carefully checked the other parameters, your code may mis-interpret this condition.
Another area where you need to be careful when using Windows Asynchronous I/O is application shutdown. There may be a number of pending I/O operations that have been queued to the I/O completion port. It is your responsibility to finish processing all of these I/O operations (possibly by first closing the socket and then handling each failed I/O completion event) and release any resources that were allocated for the I/O operations. Failing to do this will likely result in a memory leak for the application.
The moral of the story is to always read the entire MSDN documentation page and make sure your code handles all of the possible combinations of return values!
April 2, 2008 | 2 Comments
I spend most of my time developing software in C/C++, and have done so for many years now. One thing that always catches me by surprise is when I find code written by someone who decides to put implementation details of a function or method in a header file. The only reason I can come up with for why developers would do this is pure laziness.
Let’s face it, C and C++ are such a pain in the but. I mean, each ADT or Class needs two files; a .h and .c/.cpp. It sure would be easier to just lump all the stuff in a single file. Well, since C/C++ can’t generally handle that we might as well sprinkle some of the code into the .h file and some of it into the .cpp file. The compiler really doesn’t care where the code is. And, to top it off, switching between files in most editors takes at least one keystroke. Whoooaaa – what a burden for a busy developer.
Of course, this has been written about by numerous people on the web as well as having been covered by many technical journals and books. The concept is to keep the interface in one file and the implementation in another. I am still amazed to find that people routinely place implemenation details in the header files of C++ classes. All this does is slow down compile times. Some might say “So what, it doesn’t really matter anyhow. The program still compiles.” Well I say life is too short to spend all your time waiting for the compiler to recompile code that it already compiled, and for which there is no actualy reason to recompile at this point.
It all comes down to dependency management. Developers need to understand how the pieces of their programs interact, how that interaction impacts the build speed for the application, and be aware of techniques they can use to minimize the dependencies between components in their applications.
So, why is it such a bad idea to put implementation details into a header file? There are a number of design principles that would suggest separating interface from implementation pays dividens over the lifetime of an application.
When implementation details creep into an interface header everyone suffers. The compiler has to recompile many more modules each time an implementation change is made. Usually these recompiles are completely unnecessary since all the other modules require is the interface definition from the header file. The problem is that the compiler cannot distinguish an interface change from an implementation change when all of the code is packed into a single header file.
By keeping interface and implementation seperate compile speed will improve. On all but the most trivial projects this is an important thing to keep in mind.