Lookup in std::map

The STL is a very powerful and highly-customizable C++ library (for example, you can provide custom allocators for its containers), but my impression is that sometimes the public interfaces of some classes lack some useful and convenient methods.

One example is std::map: both ATL’s CAtlMap and .NET BCL’s Dictionary classes offer a convenient lookup method (CAtlMap::Lookup and Dictionary.TryGetValue respectively).

Unfortunately, there is nothing similar in STL’s std::map. The logic flow of operations for this class is:

1. call the map::find method passing the key; this method returns an iterator;

2. if the returned iterator equals map::end, the key is not contained in the map;

3. if the returned iterator is valid, the value associated with the given key can be found in iterator->second.

That’s not very intuitive and convenient (IMHO). Fortunately, we can embedd this sequence of operations in a template function, as follows:

//------------------------------------------------------------------------
// FUNCTION: lookup
//
// DESCRIPTION:
// Given an instance of std::map, this function checks if the specified key
// is contained in the map.
// If so, the function copies the value associated with the key in 'value'
// parameter, and returns true.
// If the key is not contained in the map, the function returns false
// (and the 'value' parameter is undefined).
//------------------------------------------------------------------------
template <class Key, class Value, class Compare, class Allocator>
bool lookup(
  std::map<Key, Value, Compare, Allocator> const& theMap,
  typename std::map<Key, Value, Compare, Allocator>::key_type const& key,
  typename std::map<Key, Value, Compare, Allocator>::mapped_type & value
)
{
  // Search for the specified key in the map
  auto it = theMap.find(key);
 
  // If the key is not found in the map, just return false
  if (it == theMap.end())
  {
    return false;
  }
 
  // Key found in map.
  // Copy the associated value back to the caller
  value = it->second;
 
  // Key found
  return true;
}

EDIT 2010-12-15: Thanks Stephan ‘STL’ for enlightment on a template argument deduction issue.

EDIT 2017-01-12: Used Auto SyntaxHighlighter for C++ source code.

Astronomy Picture of the Day with Windows 7 x64

Michael Dunn developed an interesting Gadget for Browsing the Astronomy Picture of the Day.

However, using the original version published on CodeProject, I failed to install the gadget on Windows 7 x64. (Browsing the comment section, it seems I was not alone.)

Fortunately, source code is available in the download package. The gadget uses an helper COM object, written in C++ with good old VC6. I imported the C++ project in VS2008 and rebuilt for x64 (in fact, to my knowledge, it is impossible to do 64-bit builds using VC6). After repackaging the gadget with the 64-bit COM object, the APOD viewer correctly shows up in Windows 7 x64.

The x64 build is attached to this post.

Building Double-NUL-Terminated Strings

EDIT (2016-10-11): New modern C++11 code available.

There was an interesting post on Raymond Chen’s blog about double-null-terminated strings.

Double-NUL-terminated strings have some pros, like reducing heap fragmentation and offering good locality: in fact, the strings are allocated in memory sequentially, and not scattered around.

Another benefit of double-NUL-terminated strings is marshaling an array of strings through a pure-C-interface DLL.

In fact, for a C++ programmer, the most natural way of storing an array of strings would be to use something like std::vector<CString> (or MFC CStringArray container). But how could we pass an array of strings at the boundaries of a pure-C-interface DLL? One solution could be to use a SAFEARRAY of BSTR‘s, from COM.

But another one (IMHO, simpler) could be to just use double-NUL-terminated strings.
This technique was proposed as an answer in a post in the Visual C++ MFC and ATL MSDN Forum.

Here is a simple C++ code to build a double-NUL-terminated string from a vector of CString’s:

//------------------------------------------------------------------------
// Builds a double-NUL terminated string from a vector of CString's.
// The caller must release allocated memory using ::LocalFree.
// Returns NULL in case of allocation error.
//------------------------------------------------------------------------

wchar_t * BuildDoubleNulString(const std::vector<CString>& strings )
{
    //
    // If the input string array is empty, just build an empty string.
    //
    if (strings.empty())
    {
        // Allocate memory using Win32 heap allocator
        wchar_t * emptyDoubleNulString = reinterpret_cast<wchar_t *>(
            ::LocalAlloc(
                LPTR,                   // fixed + zero init
                2 * sizeof(wchar_t)     // 2 Unicode characters
            ));
        if (emptyDoubleNulString == NULL)
        {
            // Alloc error
            return NULL;
        }
        return emptyDoubleNulString;
    }

    //
    // Calculate the total number of characters to build
    // the double-NUL terminated string.
    //
    size_t totalChars = 0;
    for (size_t i = 0; i < strings.size(); i++)
    {
        // Get length of current string, including terminating
        totalChars += (strings[i].GetLength() + 1);
    }

    // Consider adding a termination, so add +1 to required char count
    totalChars++;
 
    //
    // Build the double-NUL terminated string
    //
    wchar_t * result = reinterpret_cast<wchar_t *>(
        ::LocalAlloc(
            LPTR,                        // fixed + zero init
            totalChars * sizeof(wchar_t) // totalChars Unicode characters
        ));
    if (result == NULL)
    {
        // Allocation error
        return NULL;
    }

    wchar_t * dest = result;
    for (size_t i = 0; i < strings.size(); i++)
    {
        // Get current string length
        size_t currLen = strings[i].GetLength();

        // Can't have empty strings inside a double-NUL-terminated string
        ATLASSERT(currLen != 0);

        // Copy current string to destination memory
        memcpy(dest, strings[i].GetString(), currLen * sizeof(wchar_t));

        // No need to terminate current string
        //  dest[currLen] = 0;
        // because memory was allocated with zero-init flag.    

        // Move destination to next string slot
        dest += (currLen + 1);
    }

    // No need to add terminating ,
    // because memory was allocated with zero-init flag.
    //result[totalChars - 1] = 0;

    return result;
}

Note that LocalAlloc is used to allocate heap memory for the double-NUL-terminated string, because this memory should be freed by some client code outside the DLL, and it is fundamental that the code which allocates memory and the code which frees memory need to use the same allocator. So, e.g. if a DLL compiled with VC8 builds a double-NUL-terminated string allocating memory using new[], and this memory is freed using delete[] from some code built using VC9, there is a mismatch between allocators; using LocalAlloc/LocalFree prevents that kind of problem.

Visualizers for Visual Studio (CStringArray and shared_ptr)

Visualizers are a cool and useful feature available in modern versions of Visual Studio (VS2005, 2008 and 2010).

Recently, in the Visual C++ MFC and ATL MSDN Forum there was a question about examining the content of a CStringArray MFC collection in the debugger.
I wrote a simple CStringArray visualizer to solve that problem; its source code is attached here.

For those interested in a boost::shared_ptr visualizer, there is one available here as well.

 

Shell Extensions Tutorials

EDIT: Check out my Context Menu Shell Extension Pluralsight course!

Writing shell extensions is one of those programming tasks in which C++ (with the help of a library like ATL) excels.

(A Microsoft guy explained here why it is better to avoid .NET for writing shell extensions.)

Michael Dunn (a former Visual C++ MVP) wrote a very interesting series of tutorials on CodeProject on developing shell extensions:

1. A step-by-step tutorial on writing shell extensions.
2. A tutorial on writing a shell extension that operates on multiple files at once.
3. A tutorial on writing a shell extension that shows pop-up info for files.
4. A tutorial on writing a shell extension that provides custom drag and drop functionality.
5. A tutorial on writing a shell extension that adds pages to the properties dialog of files.
6. A tutorial on writing a shell extension that can be used on the Send To menu.
7. A tutorial on using owner-drawn menus in a context menu shell extensions, and on making a context menu extension that responds to a right-click in a directory background.
8. A tutorial on adding columns to Explorer’s details view via a column handler shell extension.
9. A tutorial on writing an extension to customize the icons displayed for a file type.

 

Some links on writing exception-safe code in C++

I found a very interesting thread on StackOverflow about writing exception safe code in C++:

C++: do you (really) write exception safe code?

The first answer is worth reading.

And, as already written in the aforementioned thread, detailed information on this subject can be found on GotW website, too:

GotW #59: Exception-Safe Class Design, Part 1: Copy Assignment

GotW #60: Exception-Safe Class Design, Part 2: Inheritance

GotW #61: CHALLENGE EDITION: ACID Programming 
 

The secret QueryInterface call of CComPtr

CComPtr is a convenient smart pointer ATL class to manage reference counting of COM objects.
However, it seems that sometimes smart pointers are too smart… In particular, I’m referring to the secret QueryInterface‘ing assignment operator discussed by Jared Parsons on his blog:

http://blogs.msdn.com/jaredpar/archive/2009/11/04/type-safety-issue-when-assigning-ccomptr-t-instances.aspx

The problem is the IUnknown::QueryInterface call performed by AtlComQIPtrAssign in the following templated assignment operator overload of CComPtr:

template <typename Q>

T* operator=(_In_ const CComPtr<Q>& lp) throw()

{

  if( !IsEqualObject(lp) )

  {

    return static_cast<T*>(AtlComQIPtrAssign((IUnknown**)&p, lp, __uuidof(T)));

  }

  return *this;

}

As an example, the following C++ code compiles fine (and I think it shouldn’t) on VC9 (VS2008 SP1):

#include <atlcomcli.h>

 

int main()

{

    CComPtr<IMarshal> sp1;

    CComPtr<IPersist> sp2;

 

    // I think the following statement should not compile,

    // but instead it does compile…

    sp1 = sp2;

 

    return 0;

}

Frankly speaking, I consider this behavior of CComPtr a bug; in fact, CComPtr isn’t supposed to call QueryInterface automatically: there’s CComQIPtr for that.
A possible fix to the aforementioned CComPtr behavior (bug) could be to redefine the templated assignment operator using implicit conversion for underlying raw pointers (instead of using IUnknown::QueryInterface via AtlComQIPtrAssign), e.g.:

    template <typename Q>

    T* operator=(_In_ const CComPtr<Q>& lp) throw()

    {

        return (*this = lp.p);

    }

 

A VS2008 solution with sample C++ code including the fix to CComPtr is attached to this blog post.

Thanks to Igor Tandetnik for private communication about this issue.