C++

FlexUnit, Silverlight and other Random Thoughts

August 26th, 2008 / Tales from a Trading Desk

  • FlexUnit is now out in Open Source land. Hopefully Adobe can begin to provide more enterprise development tools. The one downside of FlexUnit is that there appears to be no console mode, which is unfortunate is your running on an enterprise build plant (
  • No surprises in this list of Silverlight RIA applications. It’s unfortunate that the RIA I was instrumental in building last year isn’t in this list (
  • Oslo insights
  • Looks like Steve had to pull the BWM surface video :(, but at least there are a number of other Vectorform Surface video’s still online - Mercedes-Benz etc
  • REST with WCF - way to much REST in my life these days
  • C++0x: Interview with Bjarne Stroustrup
  • With Amazon continuing to add to the cloud, one has to ask if Oslo will provide the Microsoft Cloud?
  • NVISION 2008 has some impressive video’s. CPU’s continue to play to “financial market analyses”
  • Are Panamaps (A Multi-Layered Map) useful in finance?
  • Moth on Make Object ID
  • As blogged elsewhere, Photosynth is Released.
  • Kind of cool to see that Linden is rolling out Mono servers
  • Google mojo?

Visual C++ in Short: Determining whether a path refers to a file system object

July 31st, 2008 / Kenny Kerr : Technology

If you’ve been programming Windows for a while (prior to Windows 2000) you may well have come across a number of techniques to determine whether a path refers to a file system object such as a file or directory.

One approach is to check the result of the CreateFile function but this approach has a number of pitfalls. Checking whether a path refers to a file system object should not change the state of the file system object, which CreateFile does in most cases. You can combat this by playing around with the various flags. For example, if you only specify FILE_READ_ATTRIBUTES as the desired access then the file’s last access date won’t be updated. Of course you may not have the necessary authorization to open the file handle at all. There are also other headaches associated with this approach such as remembering to close the file handle should the call to CreateFile succeed. Determining whether the file handle refers to a file or directory involves additional function calls.

Another solution is to use the FindFirstFile function but it gets a lot more data than you might need and you also need to remember to close the search handle.

The shell provides the PathFileExists function which is simpler than the approaches mentioned thus far but is limited in that it does not distinguish between files and directories. Still, if that’s good enough then here’s all you need to do:

const BOOL exists = PathFileExists(L"<some path>");

To be able to distinguish between files and directories involves checking the attributes of the file system object. The simplest way to get a file’s attributes is with the GetFileAttributes function introduced with Windows 2000. Of course if it fails to return the file attributes you can call the GetLastError function to find out why. That in turn provides a great way to determine whether the path refers to a file system object at all. It can also tell you other useful information such as whether the path is even valid.

The beauty of this model is that you get to decide just how much information you need. For example if you only want to know whether the path exists you can simply check whether GetFileAttributes returns INVALID_FILE_ATTRIBUTES or not. Alternatively you can distinguish between different classes of failure.

The following example shows a simple helper function that singles out the ability for the system to find the specified path from other failures. If a file system object exists it returns S_OK. If the path is well formed but the system cannot find the path or file then it returns S_FALSE. In all other cases it simply returns the specific failure as an HRESULT. It even optionally tells you whether the file system object is a directory or not.

HRESULT FileExists(PCWSTR fileName, bool* isDirectory)
{
   ASSERT(0 != fileName);

   const DWORD attributes = ::GetFileAttributes(fileName);

   if (INVALID_FILE_ATTRIBUTES == attributes)
   {
       const DWORD error = ::GetLastError();

       if (ERROR_FILE_NOT_FOUND == error ||
           ERROR_PATH_NOT_FOUND == error)
       {
           return S_FALSE;
       }
       else
       {
           return HRESULT_FROM_WIN32(error);
       }
   }

   if (0 != isDirectory)
   {
       *isDirectory = 0 != (FILE_ATTRIBUTE_DIRECTORY & attributes);
   }

   return S_OK;
}

You could for example identify syntax errors using the ERROR_INVALID_NAME error code:

bool isDirectory = false;
const HRESULT result = FileExists(L"<some path>", &isDirectory);

if (S_OK == result)
{
    if (isDirectory)
    {
        wprintf(L"Its a directory");
    }
    else
    {
        wprintf(L"Its a file");
    }
}
else if (S_FALSE == result)
{
    wprintf(L"Not found");
}
else
{
    if (HRESULT_FROM_WIN32(ERROR_INVALID_NAME) == result)
    {
        wprintf(L"The syntax is incorrect");
    }
    else
    {
        // Something else is wrong...
        wprintf(AtlGetErrorDescription(result));
    }
}

Incidentally, the PathFileExists function I mentioned above uses GetFileAttributes internally if it determines that you’re running on a supported version of Windows. In other words it’s a reasonable fallback if you need to support older operating systems.

There are also various shortcuts depending on what you intend to do with the path. For example if you just want to create a file and make sure it doesn’t already exist you can simply specify the CREATE_NEW creation disposition and the CreateFile function will fail if the specified file already exists.

If you’re looking for one of my previous articles here is a complete list of them for you to browse through.

Produce the highest quality screenshots with the least amount of effort! Use Window Clippings.

Practical PLT Part 5: A Parser Generator

July 29th, 2008

At this point we’ve developed a complete, though very simple, interpreter and runtime environment.  To some degree, this interpreter is all we need.  It can express any function, it can easily be extended, it has a simple parser, and it has a working garbage collector.  What more could we ask for?  Life is good.

Life is good, that is, until we ask somebody else to use it.  Their first response is probably an annoyance at the syntax — it’s a little surprising to have to write (+ 1 1) after grade school has burned 1 + 1 into our minds — and, truth be told, the S-Expression syntax isn’t the most natural or compact for every problem.

Luckily we can, with a little work, entirely eliminate this complaint by creating a parser generator — a function that takes as input a grammar (a formal description of a language), and produces as output a parser for that language.

Read the rest of this entry »

Windows with C++: Asynchronous WinHTTP

July 29th, 2008 / Kenny Kerr : Technology

My latest Windows with C++ column in the August 2008 issue of MSDN Magazine is now online: Asynchronous WinHTTP.

This article had a bit of a rough time in the editing process and it’s not quite as polished as I would like. Nevertheless it’s still a good read and should give you a good starting point for building high performance and highly responsive HTTP client applications.

It was also heavily edited to meet the limited space requirements of print publication and some sections were dropped. One of them was a section on the positioning of WinHTTP compared to WinInet:

Veteran Windows developers may remember the Windows Internet (WinInet) API that has been around for years.  WinInet still provides a number of unique features such as support for FTP, credential caching, and user interface support. On the other hand it is not an ideal solution for service applications. It is also not suitable if your application needs to manage its own credentials, you don’t want to introduce user interface prompts, or don’t want to rely on Internet Explorer for proxy configuration.

The first paragraph in the Request Cancellation section was also edited to the point where it is incorrect and quite misleading. It should read:

WinHTTP provides a less error-prone model for asynchronous completion when compared to WinInet since your application is always notified of the completion of an operation through the callback function. On the hand, since worker threads are used to execute the callback function, cancelling a request does require some attention to detail.

Finally the section entitled Determining Proxy Settings was cut entirely from the print issue but is available as a sidebar in the online issue, although the associated screenshot was omitted.

Phew. Hopefully these minor issues will be straightened out eventually.

If you’re looking for one of my previous articles here is a complete list of them for you to browse through.

Produce the highest quality screenshots with the least amount of effort! Use Window Clippings.

Visual C++ in Short: Converting between Unicode and UTF-8

July 24th, 2008 / Kenny Kerr : Technology

The Windows SDK provides the WideCharToMultiByte function to convert a Unicode, or UTF-16, string (WCHAR*) to a character string (CHAR*) using a particular code page. Windows also provides the MultiByteToWideChar function to convert a character string from a particular code page to a Unicode string. These functions can be a bit daunting at first but unless you have a lot of legacy code or APIs to deal with you can just specify CP_UTF8 as the code page and these functions will convert between Unicode UTF-16 and UTF-8 formats. UTF-8 isn’t really a code page in the original sense but the API functions lives on and now provide support for UTF conversions.

ATL provides a set of class templates that wrap these functions to simplify conversions even further. It takes a fairly efficient and elegant approach to memory management (compared to previous versions of ATL) that should serve you well in most cases. CW2A is a typedef for the CW2AEX class template that wraps the WideCharToMultiByte function. Similarly, CA2W is a typedef for the CA2WEX class template that wraps the MultiByteToWideChar function.

In the example below I start with a Unicode string that includes the Greek capital letters for Alpha and Omega. The string is converted to UTF-8 with CW2A and then back to Unicode with CA2W. Be sure to specify CP_UTF8 as the second parameter in both cases otherwise ATL will use the current ANSI code page.

Keep in mind that although UTF-8 strings look like characters strings, you cannot rely on pointer arithmetic to subscript them as the characters may actually consume anywhere from one to four bytes. It’s also possible that Unicode characters may require more than two bytes should they fall in a range above U+FFFF. In general you should treat user input as opaque buffers.

#include <atlconv.h>
#include <atlstr.h>

#define ASSERT ATLASSERT

int main()
{
    const CStringW unicode1 = L"\x0391 and \x03A9"; // 'Alpha' and 'Omega'

    const CStringA utf8 = CW2A(unicode1, CP_UTF8);

    ASSERT(utf8.GetLength() > unicode1.GetLength());

    const CStringW unicode2 = CA2W(utf8, CP_UTF8);

    ASSERT(unicode1 == unicode2);
}

 

If you’re looking for one of my previous articles here is a complete list of them for you to browse through.

Produce the highest quality screenshots with the least amount of effort! Use Window Clippings.

Visual C++ in Short: Encoding and decoding with Base64

July 22nd, 2008 / Kenny Kerr : Technology

Base64 is a popular encoding to convert arbitrary data into a format that can be transmitted as an ASCII string. ATL provides a few functions that implement the Base64 specification.

To encode with Base64, start by allocating a buffer large enough to hold the Base64 string. The Base64EncodeGetRequiredLength function calculates how much space is required. The result of this function may be slightly larger than the actual Base64 string as it favors performance over accuracy.

The Base64Encode function performs the actual encoding. Its first two parameters specify the data to encode as well as the length in bytes. The third parameter identifies the destination buffer for the character string. The fourth parameter is an in/out parameter that on input specifies the size of the destination buffer and on output specifies the actual length of the Base64 string.

The following helper function wraps this logic and uses ATL’s string class to properly allocate and truncate the Base64 string buffer:

CStringA ToBase64(const void* bytes, int byteLength)
{
    ASSERT(0 != bytes);

    CStringA base64;
    int base64Length = Base64EncodeGetRequiredLength(byteLength);

    VERIFY(Base64Encode(static_cast<const BYTE*>(bytes),
                        byteLength,
                        base64.GetBufferSetLength(base64Length),
                        &base64Length));

    base64.ReleaseBufferSetLength(base64Length);
    return base64;
}

To decode with Base64, start by allocating a buffer large enough to hold the decoded data. If the data can have a variable length you can just allocate a byte array that is the same length as the Base64 string since the decoded data will always be somewhat smaller. ATL provides the Base64DecodeGetRequiredLength function but it simply returns its argument.

The Base64Decode function performs the actual decoding. Its first two parameters specify the Base64 string and its length. The third parameter identifies the destination buffer for the decoded data. The fourth parameter is an in/out parameter that on input specifies the size of the destination buffer and on output specifies the actual length of the decoded data.

The following example shows how to encode and decode the SYSTEM_INFO data structure:

#include <atlenc.h>
#include <atlstr.h>

#define ASSERT ATLASSERT
#define VERIFY ATLVERIFY

CStringA ToBase64(const void* bytes, int byteLength);

int main()
{
    SYSTEM_INFO info1 = { 0 };
    ::GetNativeSystemInfo(&info1);

    const CStringA base64 = ToBase64(&info1, sizeof(SYSTEM_INFO));

    SYSTEM_INFO info2 = { 0 };
    int byteLength = Base64DecodeGetRequiredLength(sizeof(SYSTEM_INFO));

    if (!Base64Decode(base64, base64.GetLength(), reinterpret_cast<BYTE*>(&info2), &byteLength))
    {
        // The string could not be decoded.
    }

    ASSERT(sizeof(SYSTEM_INFO) == byteLength);
    ASSERT(0 == memcmp(&info1, &info2, sizeof(SYSTEM_INFO)));
}

If you’re looking for one of my previous articles here is a complete list of them for you to browse through.

Produce the highest quality screenshots with the least amount of effort! Use Window Clippings.

Visual C++ in Short: Converting between numbers and strings

July 20th, 2008 / Kenny Kerr : Technology

C++ developers have a number of options available to them for converting between numbers and strings, few of which are very appealing. Most developers are familiar with the likes of atoi and itoa from the C Run-Time Library. The main problem is that these functions don’t have a coherent way of reporting errors. Although there have been some attempts to improve these functions, most notably the addition of the security enhancements introduced by Microsoft, they are still not very helpful.

Fortunately the Windows SDK includes a very comprehensive collection of functions that it inherited from OLE Automation to convert between variant-compatible types. These functions don’t actually require you to use variants or even initialize OLE or COM. They merely provide the functionality for converting between many of the types that you could store in a variant.

The functions are declared in OleAuto.h and take the form VarXxxFromYyy where Xxx is the desired type and Yyy is the original type of the data. You can use “Var[^ ]+From[^ (]+” to search for them from within Visual Studio.

 

The functions for converting strings to numbers are prototyped as follows:

HRESULT VarXxxFromStr(const WCHAR* string, LCID localeId, ULONG flags, T* number);

The source is a pointer to a Unicode string (and does not have to be a BSTR). The locale identifier affects how the string is interpreted. You can for example use the user’s regional settings as defined by the current thread’s locale identifier using the GetThreadLocale function. Alternatively you can specify LOCALE_INVARIANT if you need the conversions to be independent of the user’s locale. This might be the case if you’re using the text form of a number not to display to the user but rather to persist in some format like XML. The flags are mostly for controlling date and time conversions and should be zero in most other cases.

The following example shows how to convert a string to a double in a locale-independent manner:

double value = 0;

const HRESULT result = ::VarR8FromStr(L"1234.567",
                                      LOCALE_INVARIANT,
                                      0, // flags
                                      &value);

if (FAILED(result))
{
    // The HRESULT describes why the conversion failed,
    // e.g. DISP_E_TYPEMISMATCH, DISP_E_OVERFLOW
}

ASSERT(1234.567 == value);

The functions for converting numbers to strings are prototyped as follows:

HRESULT VarBstrFromYyy(T number, LCID localeId, ULONG flags, BSTR* string);

These functions all return the strings as BSTR values so the caller is responsible for freeing them using the SysFreeString function. A better approach is to use ATL’s CComBSTR wrapper class.

The following example shows how to convert a double to a string using the locale associated with the current thread and then converts the string back to a double again:

#include <atlbase.h>

#define ASSERT ATLASSERT

int main()
{
    double double1 = 1234.567;

    CComBSTR string;

    HRESULT result = ::VarBstrFromR8(double1,
                                     ::GetThreadLocale(),
                                     0, // flags
                                     &string);

    if (FAILED(result))
    {
        // The HRESULT describes why the conversion failed,
        // e.g. E_OUTOFMEMORY
    }

    double double2 = 0;

    result = ::VarR8FromStr(string,
                            ::GetThreadLocale(),
                            0, // flags
                            &double2);

    if (FAILED(result))
    {
        // The HRESULT describes why the conversion failed,
        // e.g. DISP_E_TYPEMISMATCH, DISP_E_OVERFLOW
    }

    ASSERT(double1 == double2);
}

Keep in mind that the thread locale can change at any time so you must not persist a localized version of a number as you may not be able to parse it later on. It is however useful for displaying and accepting input from the user.

If you’re looking for one of my previous articles here is a complete list of them for you to browse through.

Produce the highest quality screenshots with the least amount of effort! Use Window Clippings.

Visual C++ in Short: Regular Expressions

July 18th, 2008 / Kenny Kerr : Technology

ATL includes a lightweight regular expression implementation. Although originally part of Visual C++, it is now included with the ATL Server download.

The CAtlRegExp class template implements the parser and matching engine. Its single template argument specifies the character traits such as CAtlRECharTraitsW for Unicode and CAtlRECharTraitsA for ANSI. The template argument also has a default argument based on whether or not _UNICODE is defined.

The CAtlREMatchContext class template provides an array of match groups for a successful match of a regular expression. It has the same default template argument as CAtlRegExp.

In the example below, CAtlRegExp’s Parse method is used to convert the regular expression into an instruction stream that is then used by the Match method to efficiently match the input string. Each match group is defined by a start and end pointer, defining the range of characters so that a copy does not have to be made if it is not needed.

The regular expression grammar is defined at the top of the atlrx.h header file.

#include <atlrx.h>
#include <atlstr.h>

#define ASSERT ATLASSERT

int main()
{
    CAtlRegExp<> regex;
    const REParseError status = regex.Parse(L"^/blog/{\\d\\d\\d\\d}/{\\d\\d?}/{\\d\\d?}/{\\a+}$");
    ASSERT(REPARSE_ERROR_OK == status);

    CAtlREMatchContext<> match;

    if (regex.Match(L"/blog/2008/7/16/SomePost", &match))
    {
        ASSERT(4 == match.m_uNumGroups);

        PCWSTR start = 0;
        PCWSTR end = 0;

        match.GetMatch(0, &start, &end);
        const UINT year = _wtoi(start);

        match.GetMatch(1, &start, &end);
        const UINT month = _wtoi(start);

        match.GetMatch(2, &start, &end);
        const UINT day = _wtoi(start);

        match.GetMatch(3, &start, &end);
        const CString name(start, end - start);

        wprintf(L"Year: %d\n", year);
        wprintf(L"Month: %d\n", month);
        wprintf(L"Day: %d\n", day);
        wprintf(L"Name: %s\n", name);
    }
}

If you’re looking for one of my previous articles here is a complete list of them for you to browse through.

Produce the highest quality screenshots with the least amount of effort! Use Window Clippings.

Practical PLT Part 4: A Garbage Collector

June 24th, 2008

In the previous articles of this series we’ve seen how to create a simple Scheme interpreter, then how to write an S-Expression parser to feed the interpreter, and in the last article we saw how to most conveniently bind C++ functions to our interpreter with the strategic application of template classes and a “meta-circular” code-generator that built up a vital part of our interpreter (using our interpreter to do it).

Though we’ve come a long way, there’s still one glaring hole in our interpreter design: we’ve left the allocate<T> function unspecified.  This function is meant to allocate a garbage collected value of type T, which implies that we’ve got to write a garbage collector.  In this article, that’s exactly what we’ll do.

Read the rest of this entry »

Parallel Programming in Native Code

June 6th, 2008 / Kenny Kerr : Technology

Rick Molloy just mentioned to me that he’s created a new blog on MSDN to coincide with Stephen’s talk at TechEd today about the Concurrency Runtime for Visual C++.

Parallel Programming in Native Code

Welcome to the Parallel Programming in Native Code blog.  I started this blog so that I and others on my team would have a place to talk about topics relating to native concurrency.  I want to use this blog to provide early looks into what we’re thinking about, give announcements about any publicly available content or CTPs and of course respond to feedback that we receive from readers and customers...

 

Quick Update

May 21st, 2008 / Kenny Kerr

I’m doing some traveling over the next few days and will unfortunately be offline for most of that time. I will be back online on Tuesday so if you’ve sent me an email, please don’t expect a response before then.

I’ve also made some small changes to the Window Clippings order handling to make the process run a bit smoother and ensure that you receive your license keys promptly and reliably. This will hopefully reduce the number of times I need to send license keys out manually.

I also made the change from US dollars to Canadian dollars. This won’t really effect anyone as the currencies are mostly hovering around 1=1 but it will reduce processing costs for me as I do my banking in Canadian dollars and the exchange rate provided by the payment processor is quite outrageous.

On a different note I recently submitted my latest column for MSDN Magazine. This one is about writing high performance asynchronous HTTP clients in native C++. Look for it around July. I’m also going to start covering the upcoming C++0x standard in my column. C++0x aims to make it easier to build libraries and in particular template metaprogramming. It allows you to produce even more efficient code while making it easier to write and diagnose compile-time errors related to templates and will thus make it easier to learn for novices. And that’s just the tip of the iceberg. Exciting times!

© 2008 Kenny Kerr

Beef Up Windows Apps with the Visual C++ 2008 Feature Pack

May 6th, 2008 / Kenny Kerr

Back in December of last year the Visual C++ team asked me to write an article for MSDN Magazine about the new Visual C++ 2008 Feature Pack. Well the article has finally made it into print in the May 2008 issue and you can also read it online.

C++ Plus: Beef Up Windows Apps with the Visual C++ 2008 Feature Pack

As a developer using Visual C++ , you may have felt a bit left behind in recent years as it seems like Microsoft has added more new features and functionality to Visual C#® than to Visual C++®. The truth is that although the Visual C++ compiler has continued to improve in a variety of areas including performance, security, and standards conformance, little has been done in the way of new library and productivity features for quite some time. And while MFC was updated to better support Windows Vista®, more could have been done. Now, however, to better support developers who use native code and MFC in particular, Microsoft has released the Visual C++ 2008 Feature Pack. Here's your evidence of a renewed commitment to Visual C++.

Enjoy!

If you’re looking for one of my previous articles here is a complete list of them for you to browse through.

© 2008 Kenny Kerr

Windows with C++: Windows Imaging Component (Part 1)

April 14th, 2008 / Kenny Kerr

My latest column is now available in the April 2008 issue of MSDN Magazine. This is part 1 of a 3 part series about the Windows Imaging Component that ships with Windows Vista as well as the .NET Framework 3.0 and later.

Windows with C++: Windows Imaging Component Basics

This month I'll show you how to use WIC to encode and decode different image formats and a few things in between. Next time I'll explore some of the more advanced features and show you how to extend WIC with your own imaging codecs.

Enjoy!

If you’re looking for one of my previous articles here is a complete list of them for you to browse through.

© 2008 Kenny Kerr

Microsoft MVP 2008

April 1st, 2008 / Kenny Kerr

I just heard that I have received the Microsoft MVP award again this year for my contributions to the Visual C++ community. Thanks to my friends at Microsoft. It’s been a pleasure getting to know all of you. Unfortunately the MVP Summit is no longer just “down the road” for me. Maybe next year. My colleague, Matt Davey , just got his first award this year. Congrats pal.

Microsoft MVP 2008

April 1st, 2008 / Kenny Kerr

I just heard that I have received the Microsoft MVP award again this year for my contributions to the Visual C++ community. Thanks to my friends at Microsoft. It’s been a pleasure getting to know all of you.

Unfortunately the MVP Summit is no longer just “down the road” for me. Maybe next year.

My colleague, Matt Davey, just got his first award this year. Congrats pal.

Some exciting news for C++ developers

March 31st, 2008 / Kenny Kerr

Herb Sutter announced some very exciting news coming from the C++ committee. We can look forward to lambda expressions, closures, inheriting constructors, nested exceptions, and more.

There’s no telling yet when exactly these additions will make their way into compilers like Visual C++ but approval by the committee is certainly a good kick start. Combine this with the previously approved TR1 update and I would expect the next major release of Visual Studio to be a very exciting one for C++ developers.

I have written an article on the TR1 and MFC updates to Visual C++ that will be published in MSDN Magazine in the next month or two. Stay tuned!

 

Windows with C++: Windows Services Enhancements

February 17th, 2008 / Kenny Kerr

My latest column is now available in the Visual Studio 2008 launch issue of MSDN Magazine. Windows with C++: Windows Services Enhancements Windows Vista and Windows Server 2008 bring some significant changes that make it simpler to produce services that are more secure and responsive. Enjoy! If you’re looking for one of my previous articles here is a complete list of them for you to browse through. © 2008 Kenny Kerr

CUDA: GPU architecture for NVidia cards

February 4th, 2008

This morning fellow 49′er Doug and I spoke with a colleague in Citibank who spent friday at an absolutely free boot camp for NVidias GPU development architecture. Wish we’d known about it beforehand, if nothing else for the free lunch. :)

There’s a lot of activity around building development architectures to take advantage of the compute power on Graphics Processing Units. Read the rest of this entry »

A Pocket Scene Editor

January 20th, 2008

Scene EditorI’ve made some updates to this project since I last wrote about it.

I added basic perspective-correct texture mapping (the image to the left shows the Lab49 logo mapped onto two Bézier patches, a triangle, and very awkwardly onto a cube).  I also created a very simple scene editor, which lets you add new objects (triangles, cubes or patches) to the scene and move/rotate/scale them in the YZ, XY or XZ planes.

For a straightforward (unoptimized) software renderer, it runs pretty well on my Pocket PC.  If you’d like to test it without going through the trouble of checking out the project and compiling it, you can get the binary for a Pocket PC with an ARM processor here:

editor.exe (176 KB)

Read the rest of this entry »

Unit Testing for Native C++

January 17th, 2008 / Kenny Kerr

I often get asked about unit testing native code and quite frankly I’ve never really had a good answer. Until now that is. Maria Blees was kind enough to share a unit testing framework she developed for C++ called WinUnit and I must say I’m really impressed. Go read about it now in her article published in this month’s issue of MSDN Magazine: WinUnit: Simplified Unit Testing for Native C++ Applications The opening remark also really resonated with me: “These days it can be hard not to feel downright oppressed as a native code developer—it seems like the developers using the Microsoft .NET Framework get all the cool tools!” Tell me about it! :) It seems debugging guru John Robbins has known about it for a while and is also singing its praises .