|Date:||January 3, 2007 / year-entry #3|
|Summary:||Okay, so I explained that a lot of so-called functions are really redirecting macros, function-like macros, intrinsic functions, and inline functions, and consequently, GetProcAddress won't actually get anything since the function doesn't exist in the form of an exported function. But why, then, can you GetProcAddress for IsDialogMessage? Let's take a closer look at the...|
that a lot of so-called functions are
really redirecting macros, function-like macros, intrinsic
functions, and inline functions,
Let's take a closer look at the exports from
417 1A0 0002C661 IsDialogMessage 418 1A1 0002C661 IsDialogMessageA 419 1A2 0001DFBC IsDialogMessageW
Notice that this function is exported three ways.
The last two are the ones you expect,
This phantom third function is hidden from C and C++ programs
because any attempt to call
#ifdef UNICODE #define IsDialogMessage IsDialogMessageW #else #define IsDialogMessage IsDialogMessageA #endif // !UNICODE
(Of course, you can play fancy games to remove the redirection macros; I'm just talking about the non-fancy case.) If nobody can call the function, then why does it exist?
Because of mistakes made long ago.
If you hunt through
When you don't have a time machine, you have to live with your mistakes.
In a sense, these functions are vestigial organs of Win32.
Unfortunately, like your appendix, which can get infected,
these vestigial organs can create a different sort of infection:
If you are using p/invoke to call these functions and mistakenly
override the default name declaration with
[DllImport("user32.dll", ExactSpelling=true)] public static extern bool IsDialogMessage(IntPtr hWndDlg, [In] ref MSG msg);
then you will in fact get the normally-inaccessible undecorated name, since you specified that you wanted the exact spelling. This highlights once again that you need to be alert when doing interop programming: You get what you ask for, which might not be what you actually wanted.
<-- Back to Old New Thing Archive Index