Wednesday, November 5, 2008

A Sparsely Documented Aspect of GetProceAddress

A couple of weeks ago, in the course of developing a new version of my MD5 digest library, I moved the Unicode versions of the functions into a separate library, which the main library would manage, and load only if the Windows platform on which it is running fully supports Unicode. Among other things, this meant that I needed to use the GetProcAddress Windows API function to call the functions in the Unicode satellite library. According to the documentation, on the platforms that support it, Windows exposes both ANSI and Unicode versions of this function.

Accordingly, I took the documented type of LPCSTR for the lpProcName argument to mean that the Unicode veersion of the function took a Unicode string. Silly me!

After hours of trial and failure, I repeated my Google search, and examined some of the other articles, starting with HowTo: LoadLibrary and GetProcAddress?, which gives hints of a few key elements not given sufficient emphasis in the formal documentation. The discussion on the Experts Exchange board indicated that I needed to create a typedef to match the function prototype. Less obvious is that the lpProcName argument to GetProcAddress should probably be documented as something more like char *. For this, I am indebted to the following text, taken from RE: GetProcAddress Usage.


... you will see that the lpProcName parameter is *only* configured
for const char*; there is no TCHAR derived type for the string used
here. So regarless of whether you are running with UNICODE turned
on or not, the name of a function passed to GetProcAddress is
never UNICODE formatted.


In the course of writing this article, with the knowledge learned from these and other articles, and the working code, which is part of the published source code of MD5Digest: Dynamic Link Library for Computing MD5 Digest Strings, I made a closer inspection of the included code sample.


// Call GetNativeSystemInfo if supported or GetSystemInfo otherwise.

pGNSI = (PGNSI) GetProcAddress(
GetModuleHandle(TEXT("kernel32.dll")),
"GetNativeSystemInfo");
if(NULL != pGNSI)
pGNSI(&si);
else GetSystemInfo(&si);


Although the library name in the GetModuleHandle call is wrapped in a TEXT macro, the function name string in the GetProcAddress call is not. Pretty subtle, eh?

Sunday, October 5, 2008

Could not Find Schema Information for the Element

Like Frederik Gheysels, and nearly any other developer worth his coding pad (er, editor), I like to resolve all exception reports, even warnings. Of course, there are very rare occasions when I leave a compiler warning. When I do, you can expect a comment, adjacent to the offending line, noting the warning number, and stating that the code works as designed, regardless of the warning.

In the course of sorting out one such message, "Could not Find Schema Information for the Element", which was reported when I built a new C# application, my first to incorporate application settings, I ran across two related blog articles that helped solve the problem.

The first,"Silly Config file Warnings," by Peter Richie, summarizes the cause of the problem, and provides a usable workaround, in the form of an amended DotNetConfig.xsd.

The second, ".NET 2.0: Could not find schema information for ... part 2," in Frederik Gheysels' DevLog Weblog on C# and Software Development, while it clarified and validated the first one, omitted one critical detail, which is that, after you install the new schema definition, you must restart Visual Studio for it to take effect.

Thanks to Peter and Frederik for their writings that supplied almost everything needed to solve this annoying problem.

This is hardly the first post that I've seen that was missing an essential detail. Expect to see more such gaps filled in this space.

What Is a Thought Snippet?

A thought snippet is the very essence of a Blog. It is to thoughts as a Code Snippet is to a complete C#, VB.NET, or ASP.NET program.

The intent of this collection of thought snippets is to provide permanent storage for such things as useful insights, notes about gaps in documentation that I've discovered and filled in the course of creating new software. We stand on the shoulders of others. Through this collection of notes, others will benefit from these discoveries.