Archives
-
Windows Web Services FAIL
In 2007 I published an article about the cool XmlLite API introduced with Windows Vista. Although the XmlLite developers wanted to provide a redistributable for Windows XP, they never managed to get it past the Microsoft lawyers. Eventually Windows XP Service Pack 3 was released including XmlLite but by then many developers had given up on it. I felt that this was a great embarrassment for Microsoft. But that was in the Windows Vista era. Surely things have improved in the Windows 7 timeframe.
-
Goodbye Windows with C++ and Layered Windows with Direct2D
I’ve been offline for days at a time while traveling through South Africa and just noticed that my latest Windows with C++ column, Layered Windows with Direct2D, is now live on the MSDN Magazine website.
-
Travel
Today I’m leaving for South Africa where I’ll spend 2.5 months with my family. If you have any questions about Window Clippings or my articles please be patient as I may not be able to get online to check my email as regularly.
-
Windows Web Services versus ATL SOAP
After publishing the WWS article I received some questions about how this compares to ATL’s SOAP stack. I’m certainly not trying to convince anyone to switch over to WWS but it has some benefits that may be useful in some scenarios. I also haven’t used the ATL/ServerXMLHTTP stack much so I’m probably not the best person to do a comparison. From what I can tell however it uses either WinHTTP or WinInet and MSXML. Given that there are some things I can point out
-
Windows with C++: Windows Web Services
My latest Windows with C++ column, Windows Web Services, just went live on the MSDN Magazine website. Here I’m taking a break from Direct2D to highlight the new SOAP stack introduced with Windows 7 for building both clients and servers. It’s completely native, has minimal overhead, and is incredibly fast. From the article:
-
October 2009 issue of MSDN Magazine
Those of you expecting my Windows with C++ column about Windows Web Services to appear in the October issue will have to wait another month as the article was bumped due to space constraints. I just found out yesterday myself. In the mean time you should read Rick Molloy’s latest article on the Concurrency Runtime.
-
Zune Fail
The Zune hardware products are fantastic. The new Zune HD is particularly impressive. The Zune software is a joy to use when compared to that other product that controls 99% of the market. But until Microsoft figures out how to make the Zune Marketplace and the Zune Pass subscription service available in the rest of the world (outside of the USA) this isn’t going to go anywhere.
-
Direct2D and the Desktop Window Manager
Many moons ago, when Windows Vista was still in beta, I wrote an article showing readers how to program with the Desktop Window Manager (DWM). I also followed up with another article showing readers how to display controls on glass. Both articles focused on User32/GDI which at the time was still the way to go for native application developers.
-
WinUnit is Now on CodePlex
I’m totally hooked on WinUnit. As someone who writes a lot of native code it’s just absolutely essential. Up until now the only place to get it was via the download for the article that Maria wrote for MSDN Magazine.
-
Windows with C++: Drawing with Direct2D
My latest Windows with C++ column, "Drawing with Direct2D", just went live on the redesigned MSDN Magazine website. This is really a continuation of my previous column where I introduced Direct2D. From the article:
-
I just don’t get twitter
I think I’m with Mickey on this one and may never post anything more, but to ensure that nobody confuses me with a few other notorious Kenny Kerr’s out there my twitter account is “kennykerr”.
-
Window Clippings loves Windows 7
I received a few queries about this so I thought I better just make a quick statement: Window Clippings 2.1 works great on Windows 7.
-
Windows Server 2008 R2 for MSDN Subscribers
It’s been just over a week since Windows 7 was made available to MSDN subscribers and now you can finally download the server version and with it version 2 of the best virtualization system on the planet!
-
Lenovo Website Blues
I’ve been dreaming of getting a Lenovo laptop for a few years. Don’t get me wrong, I love my Dell D630 but it may be time to upgrade soon. What frustrates me is how bad the Lenovo website experience is. Take the very appealing new T400s’ customization page:
-
Windows 7 for MSDN Subscribers
-
On the move again
Our house is now officially on the market. Anyone want to live in Tonbridge in Kent? We’re on our way back to Ontario in Canada after two years in England. This will be our last move!
In other news there have been some hiccups with scheduling at MSDN Magazine. My next article, on Direct2D again, will now appear in the September 2009 issue. I’ve also just finished another really fun article on the new Windows Web Services API that I’m really excited about. That’ll be in the October 2009 issue and I’ll probably write some more about it for the December 2009 issue.
We’re really looking forward to being back in Canada! Just as soon as we sell this house... -
Asynchronous Agents
Rick Molloy, one of the masterminds behind the new concurrency runtime (concrt) and parallel patterns library (PPL), has written an article in the latest issue of MSDN Magazine demonstrating the new asynchronous agents library with the classic dining philosophers problem.
-
Lost Carrier Pigeon
What do you when a carrier pigeon lands in your back yard seemingly lost?
-
Windows with C++: Introducing Direct2D
I’ve been away from my computer for a few days working on a house renovation project and didn’t notice that my latest Windows with C++ column came out until the mail man delivered a copy of the June 2009 issue of MSDN Magazine.
-
WTL 8.1 is coming!
After almost two years of silence there appears to be activity around WTL again. Of course this makes sense since Windows 7 is almost done. I just noticed build 8.1.9127 posted over on SourceForge.NET.
-
Visual Studio 2010 and .NET Framework 4 Beta 1 are here!
Microsoft has finally released an update to the Visual Studio 2010 preview build that showed so much promise but unfortunately was so unreliable. If you have an MSDN subscription just head over to subscriber downloads and start downloading now!
-
Resolving Windows Sleep Problems
This is more of a reminder to myself but it may come in handy for you.
-
C++ Exception Handling
A while ago I made a passing remark on my blog that I prefer not to use exceptions in native code. Some readers asked me to justify this position and I’ve been a bit reluctant to do so only because it’s a lengthy argument that I’m sure will bring a lot of passionate responses that I don’t really have the time to deal with. I was reminded of this again last night when I walked past one of our bookshelves at home and picked up my copy of John Robbins’ excellent debugging book and noticed that it has a chapter on crash handlers within which John does a good job of covering many of the reasons why I don’t use exception handling in native code. If you’re interested in this topic I would encourage you to read John’s book.
-
Exciting Changes
I’ve made a few changes to my professional life. I’ve had the opportunity to work with some really talented developers in London and I’m sorry to say goodbye to them. I’ll talk more about that in the coming weeks and months but one of the outcomes is that I’ll have much more time for my software projects. To unwind from employment (e.g. slavery :) ) I took Karin and the kids camping and boy did things change in the world of Microsoft technology in just one week. Here are just some of the announcements.
-
Another year in the MVP Award program!
Thanks to all the talented people at Microsoft.
-
Windows with C++: The Virtual Disk API in Windows 7
My latest Windows with C++ column in the April 2009 issue of MSDN Magazine is now online:
-
More on COM Safe Arrays and .NET Interop
A few years ago I wrote about P/Invoke and how it can provide benefits even when C++ Interop is available on the consuming end. Recently I’ve had to do a bit of work consuming COM safe arrays from C#. I’ve seen safe arrays trip up developers time and again so I thought I’d share some thoughts and tips on the subject.
This discussion focuses on the use of two-dimensional safe arrays. Single-dimensional safe arrays are marshalled automatically by the CLR (in most cases) but it is two-dimensional safe arrays that are often used to communicate key-value pairs such as for a map or dictionary of some kind. The trouble is that a two-dimensional safe array is really just a table of values. You can think of it as having an X axis and a Y axis. Storing key-value pairs in the table then requires a decision to be made regarding whether the keys will be stored down the Y axis as rows or along the X axis as columns. You could argue about which is better but at the end of the day you’re likely going to be at the mercy of whatever native API you’re calling.
If keys are stored down the Y axis then a particular key is indexed with the safe array’s first dimension. The first dimension will thus have as many elements as there are pairs. The second dimension will have exactly two elements with the first storing the key and the second storing the value.
On the other hand if keys are stored along the X axis then a particular key is indexed not by the first dimension but by the second. The second dimension will thus have as many elements as there are pairs. The first dimension will have exactly two elements with the first storing all the keys and the second storing all the values.
Of course not everyone naturally thinks in terms of the same coordinate space and you may need to apply a transform before it makes sense to you. Apologies to graphics developers everywhere. :)
Let’s make this a bit more concrete with an example. Here is a native container of string-double pairs implemented by ATL’s CAtlMap class:
typedef CAtlMap<CString, double> Map;
Map m_map;
The following function creates and returns a safe array keyed along the X axis using ATL’s safe array wrapper classes:
#define HR(expr) { hr = expr; if (FAILED(hr)) return hr; }
HRESULT __stdcall GetDictionaryX(SAFEARRAY** dictionary)
{
HRESULT hr;
if (0 == dictionary)
{
return E_POINTER;
}
CComSafeArrayBound bounds[2] =
{
CComSafeArrayBound(2),
CComSafeArrayBound(m_map.GetCount())
};
CComSafeArray<VARIANT> safeArray;
HR(safeArray.Create(bounds, _countof(bounds)));
LONG indices[2] = { 0 };
POSITION position = m_map.GetStartPosition();
for (; 0 != position; ++indices[1])
{
const Map::CPair* pair = m_map.GetNext(position);
indices[0] = 0;
HR(safeArray.MultiDimSetAt(indices, CComVariant(pair->m_key)));
indices[0] = 1;
HR(safeArray.MultiDimSetAt(indices, CComVariant(pair->m_value)));
}
*dictionary = safeArray.Detach();
return S_OK;
}
Briefly, the bounds define the dimensions of the safe array and the indices are used to set the values in the table.
The following function does the same thing but returns a safe array keyed along the Y axis:
HRESULT __stdcall GetDictionaryY(SAFEARRAY** dictionary)
{
HRESULT hr;
if (0 == dictionary)
{
return E_POINTER;
}
CComSafeArrayBound bounds[2] =
{
CComSafeArrayBound(m_map.GetCount()),
CComSafeArrayBound(2)
};
CComSafeArray<VARIANT> safeArray;
HR(safeArray.Create(bounds, _countof(bounds)));
LONG indices[2] = { 0 };
POSITION position = m_map.GetStartPosition();
for (; 0 != position; ++indices[0])
{
const Map::CPair* pair = m_map.GetNext(position);
indices[1] = 0;
HR(safeArray.MultiDimSetAt(indices, CComVariant(pair->m_key)));
indices[1] = 1;
HR(safeArray.MultiDimSetAt(indices, CComVariant(pair->m_value)));
}
*dictionary = safeArray.Detach();
return S_OK;
}
With the native code out of the way let’s see how we can call these functions from C#. For simplicity lets assume they’re just exported functions and not COM interface methods. The same principals apply but it’s just less sample code for me to write.
The first step is to import the functions as follows:
[DllImport("Server.dll", EntryPoint = "GetDictionaryY", PreserveSig = false)]
[return: MarshalAs(UnmanagedType.SafeArray)]
static extern object[,] NativeGetDictionaryY();
[DllImport("Server.dll", EntryPoint = "GetDictionaryX", PreserveSig = false)]
[return: MarshalAs(UnmanagedType.SafeArray)]
static extern object[,] NativeGetDictionaryX();
This just adds some metadata needed by the CLR to call the LoadLibrary and GetProcAddress functions on your behalf, how to marshal the parameters and return value, and what to do with the HRESULT.
The next step is to determine how many key-value pairs the two-dimensional array consists of. The array’s GetLength method comes in handy as you can specify the dimension whose length you are interested in:
object[,] array = NativeGetDictionaryX();
int count = array.GetLength(1);
Given the count you can now enumerate the key-value pairs using a for loop and a bit of casting:
for (int i = 0; i < count; ++i)
{
string key = (string)array[0, i];
double value = (double)array[1, i];
Console.WriteLine(key + "=" + value);
}
Needless to say this is quite error prone. It would be more desirable to use a foreach loop but the enumerator provided by the multi-dimensional array doesn’t know anything about the key-value pairs so it just returns it in a flat list. The good news is that it’s pretty easy to write your own enumerator or to be precise let the C# compiler generate one for you.
Here’s an implementation of the generic IEnumerable<TKey, TValue> interface that does just what you want for arrays keyed along the X axis:
class SafeArrayEnumerableX<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>
{
private readonly object[,] m_array;
public SafeArrayEnumerableX(object[,] array)
{
Debug.Assert(null != array);
Debug.Assert(2 == array.GetLength(0));
m_array = array;
}
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
{
int count = m_array.GetLength(1);
for (int i = 0; i < count; ++i)
{
yield return new KeyValuePair<TKey, TValue>((TKey)m_array[0, i], (TValue)m_array[1, i]);
}
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
Notice that it’s effectively doing the same looping and casting as the hand-rolled approach but in such a way that you end up with a reusable enumerator that hides all the nasty indexing and casting. With the enumerator providing a sequence of generic KeyValuePair<TKey, TValue> structures, enumerating over the pairs now becomes much more elegant:
static SafeArrayEnumerableX<string, double> GetDictionaryX()
{
return new SafeArrayEnumerableX<string, double>(NativeGetDictionaryX());
}
foreach (var pair in GetDictionaryX())
{
string key = pair.Key;
double value = pair.Value;
Console.WriteLine(key + "=" + value);
}
And that’s all there is to it. For completeness, here’s the equivalent enumerable implementation for arrays keyed along the Y axis:
class SafeArrayEnumerableY<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>
{
private readonly object[,] m_array;
public SafeArrayEnumerableY(object[,] array)
{
Debug.Assert(null != array);
Debug.Assert(2 == array.GetLength(1));
m_array = array;
}
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
{
int count = m_array.GetLength(0);
for (int i = 0; i < count; ++i)
{
yield return new KeyValuePair<TKey, TValue>((TKey)m_array[i, 0], (TValue)m_array[i, 1]);
}
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
I hope that helps. -
Windows with C++: Visual C++ 2010 and the Parallel Patterns Library
My latest Windows with C++ column in the February 2009 issue of MSDN Magazine is now online:
-
Windows 7 beta now on MSDN and Connect
You can now download the beta of Windows 7 and Windows Server 2008 R2 from MSDN subscriber downloads and from Microsoft Connect.
-
Manifest View support for DLLs
Since I blogged about my Manifest View tool I’ve had a few requests to add support for viewing manifests embedded within DLLs. It originally only supported viewing manifests embedded within executables.