How to deal with WinAPI macros overriding some function names? - c++

<windows.h> defines macroses for Ansi and Unicode versions of WinAPI.
I have a function named SendMessage in my class library. It works fine until <windows.h> is included before including my library. In this case SendMessage is overrided by the macros and the function name becomes SendMessageA or SendMessageW.
Is it possible to somehow deal with it without changing the name of the function in order to save compatibility with older versions of the library?

The real problem is that WinAPI's function definitions are at the C-preprocessor level, and so you have to write some ugly code to try to coexist with them.
If at all possible, you should rename your codebase's functions so that there is no collision with WinAPI.
Otherwise, you can write code like #undef SendMessage to undefine WinAPI's definition of this function before defining your own function.
If you need to switch between defining your own functions and using WinAPI's function macros, you can also use the #pragma push_macro and #pragma pop_macro functionality to preserve the macro before the undef and restore it afterwards.

Related

How do I resolve naming conflicts with headers that use the preprocessor to redefine common function names?

EDIT: I found a similar question, and the answers are basically that windows.h is bad and you must either rename your functions or #undef the macros: Other's library #define naming conflict
However, I believe mine is still different due to the conflicting behavior of LoadLibrary under debug and release builds.
I am programming on Windows using Visual Studio and I ran into a few peculiar issues with preprocessor directives used by windows.h and the headers it includes.
Our project had a function in its own namespace, MyProject::FileManager::CreateFile(). After including windows.h our code failed to compile due to a linker error stating that it could not resolve MyProject::FileManager::CreateFileW (note the W at the end of the function name). This was not a static function, it was a member function of a FileManager object that was being called with file_manager.CreateFile(...).
When highlighting the function in Visual Studio a tooltip displayed the following:
#define CreateFile CreateFileW
We were puzzled but just renamed the function as a workaround. However later we ran into a similar issue with the LoadLibrary function we were trying to use from the Windows API. Compiling in Debug mode, LoadLibrary was defined as LoadLibraryW() which took an LPCWSTR (wide string) as a parameter. When I tried building in Release mode this function was now defined as LoadLibraryA() which takes a normal LPCSTR. This broke our build because the code was written under the assumption that LoadLibrary took an LPCWSTR.
So, my question is, how should a programmer deal with this? Should I just wrap my calls to LoadLibrary with #ifdef's checking for Debug or Release mode? Or is there a more simple solution?
Also, I found an interesting header file on github which appears to have been created for the sole purpose of #undef'ing all these function names:
https://github.com/waTeim/poco/blob/master/include/Poco/UnWindows.h
There are few things I generally do to cope with this:
Isolate all Windows system calls in a Windows-specific layer. For example, if I'm working with the file system API, I'll typically have win/filesystem.h and win/filesystem.cpp to wrap all the calls. (This is also a good place to convert Win32 errors into std::system_error exceptions, remove unneeded/obsolete/reserved parameters, and generally make the Windows API more C++ friendly.)
Avoid using Windows-specific types. Allowing definitions like DWORD, LPTSTR and BOOL to infiltrate all levels of your code makes dealing with Windows.h that much more difficult. (And porting too.) The only files that should #include <Windows.h> should be your wrapper C++ files.
Avoid using the Windows redirection macros yourself. For example, your wrapper layer should call CreateFileW or CreateFileA directly instead of relying on the macro. That way, you don't need to depend on the Unicode/Multi-byte project setting.
Example
win/filsystem.h might contain definitions like this:
namespace win32
{
class FileHandle
{
void* raw_handle_;
public:
// The usual set of constructors, destructors, and accessors (usually move-only)
};
FileHandle CreateNewFile(std::wstring const& file_name);
FileHandle OpenExistingFile(std::wstring const& file_name);
// and so on...
}
Any part of your code can include this file to access the file system API. Since win/filesystem.h does not itself include <Windows.h>, the client code will be uncontaminated by the various Win32 macros.
The problem here is that windows.h tries to support two different string models: strings consisting of single-byte characters and strings encoded in unicode (defined by microsoft as two-byte characters). Almost all of the Windows API functions have two different versions, one that takes single-byte character strings and one that takes two-byte character strings. You're supposed to write your code with the generic names (such as CreateFile, LoadLibrary, etc.) and let windows.h take care of mapping those names to the actual API functions. For single-byte characters those two are CreateFileA and LoadLibraryA; for two-byte characters they are CreateFileW and LoadLibraryW. And there are a bajillion more, of course. You choose the model at compile time by defining the macro UNICODE in every compilation unit.
Incidentally, the 'A' suffix stands for "ANSI", and the 'W' suffix stands for "wide character".
This is particularly insidious when you write code that tries to isolate the Windows dependencies into a handful of source files. If you write a class that has a member function named CreateFile, it will be seen in source files that don't use windows.h as CreateFile, and in source files that do use windows.h as CreateFileA or CreateFileW. Result: linker errors.
There are a several ways around this problem:
always #include <windows.h> in every header file; that's a compiler performance killer, but it will work. (windows.h was a major motivator for precompiled headers in early C++ compilers targeting windows)
always use the doctored name, either CreateFileA or CreateFileW; that will work, but at the cost of losing the flexibility of being able to change the underlying string model when you're making API calls; whether that matters is up to you.
don't use any of the Windows API names; potentially painful if you use the same naming convention as Windows; not at all painful if you use snake case, i.e., all lower-case with underbars to separate words. For example, create_file. Alternatively, use a local prefix or suffix: MyCreateFile or CreateFileMine.

How to suppress #define locally?

Just caught a silly bug. I have a zip processing library with a CreateFile() function in it. Winbase.h, included somewhere deep in my headers, redefines it as CreateFileW and linker goes nuts.
Of course I will exclude winbase in this particular case. It just shouldn't be in the scope in the first place. But the theoretical question is still interesting,
Is there a way to suppress some defines locally?
You can get around the macro by putting parentheses around the name:
(CreateFile)(arguments);
This works because the macro CreateFile is a function-like macro (i.e. it takes a list of arguments in parentheses); the right parenthesis after the name doesn't match the syntax for using a function-like macro, so the preprocessor does not expand it.
Of course, the "right" solution is to name the function properly, i.e., create_file. <g>
Removing the offending header file is ALWAYS the best solution for this (especially one as large as windows.h or winbase.h - they are included far too freely for my taste in many projects).
The only other solution is #undef offending_symbol.
Of course, another important thing is "do not use names that match the Windows/Linux system call names" - but CreateFile is a very obvious name for a function that creates a file, so I can see the temptation.
Preprocessor macros have no notion of C++ scope. #defines are just text replacements. If you want to have a 'local' #define, you do something like this:
#define CreateFileW CreateFile
... // here I can use the macro
#undef CreateFileW
Or in your case
#undef CreateFileW
... // Here the macro is not available
#define CreateFileW CreateFile
There is
#undef
which removes defines (but nothing else).
Apart from the aforementioned #undef there technically is not much you can do against #defines, at least not portably.
The best way is to not use #define at all, or at least as little as possible and as constrained as possible. Sometimes you just need a macro to generate some boilerplate code a few times. Be sure to #undef that macro once you are done. The only other valid applications of #define I can think of are include guards and flags for conditional preprocessing.
For #define-deseases like the WinAPI headers you just should constrain them as much as possible. Don't use the #defined types of that API in your headers. You almost never want to use an API all over your application, so use it only in the cpps of a small layer around the API. Reducing the dependencies that way gives a lot more than just disinfecting the rest of your code.

C++ Function Type?

I'm new to, and learning C++ (know a lot of Java) and the following code confuses me...
I know this code fragment is dealing with a pointer-to-function (it's a callback, that makes sense) but what is throwing me off is the argument between the return type and the function name. What the bloody hell is that?
It looks like a type of function, but I have never heard of that and even after searching and reading about pointer-to-functions I was not able to find anything mentioning that functions could have a type.
If this is true, how does one define a function type?
Thanks, -Cody
GLFWCALL is not a type, it's a macro which is expanded to a calling convention specific to the platform, or an empty string. Here's a trimmed fragment of glfw.h:
#if defined(_WIN32) && defined(GLFW_BUILD_DLL)
#define GLFWCALL __stdcall
#elif defined(_WIN32) && defined(GLFW_DLL)
#define GLFWCALL __stdcall
#else
/* We are either building/calling a static lib or we are non-win32 */
#define GLFWCALL
#endif
Using a correct calling convention is important on x86/win32, since some of them expect the stack to be cleaned by callee and others by the caller. There can also be differences in the order of passing the arguments.
On Windows, GLFWCALL is a macro for __stdcall, and on other platforms, it's a macro for nothing.
__stdcall implements a particular calling convention, and is a compiler extension on top of normal C or C++.
Macros are pieces of code that do replacements on your code before the lexer and parser of your compiler interact with them.
The GLFWCALL is a macro that can expand to a calling convention if one is needed. Because this function will be called by external code, it has to use the calling convention that external code expects. For example, if the function puts its return value on the stack and the external code expects it in a register, boom.
The question marked part of the function signature is a preprocessor macro that is defined somewhere else in the header. Certain features on certain platforms have extra requirements.
For example functions in DLL files on the Windows platform often make use of the __declspec(dllexport) modifier but when the same header is included in a user's project they need to use __declspec(dllimport). Using a preprocessor macro for that purpose means they can just use that macro on all relevant functions and simply define the macro differently when compiling their own DLL or a user's DLL and on platforms where __declspec is irrelevant it can be defined to nothing. There are many other reasons for macros like that one.
In this particular case you can effectively pretend that macro is blank and ignore it entirely.

Is preprocessor blindly replace the defines?

I have a class that has a member function called SendMessage. No member function named SendMessageA exists in the project.
Project is multibite, so I have a define
#define SendMessage SendMessageA
If I call SendMessage somewhere in that class, will my project call SendMessage or SendMessageA ?
If the replace is made by preprocessor,the project should not compile. Right ?
But I see in a dump that SendMessageA is called ... end eip register is not in any VAD
EDIT
A more specific question: is preprocessor blindly replace the defines ? or first checks for a match in the class ?
The Preprocessor runs through your code before compilation.
So any SendMessage would be converted into a SendMessageA. The compiler will then look for a function called SendMessageA and call it.
How C++ preprocessor works
In case of #define A B preprocessor replaces ALL occurences of A with B. It is pure substitution.
Will my project call SendMessage or SendMessageA ?
Your project will call either SendMessageA or SendMessageW - depending on whether it was compiled with unicode support or not. There's no SendMessage function - it doesn't exist.
f the replace is made the project should not compile.
SendMessageA is declared within <widnows.h> (or in a header that is included from windows.h) - somewhere, and its linking info is within one of base system libraries (User32.lib, I think). If you're on windows, there's a very good chance <windows.h> is #included from somewhere, and corresponding *.lib is already in linker dependencies.
--EDIT--
A more specific question: is preprocessor blindly replace the defines ?
Yes, preprocessor blindly replaces defines. For non-blind replacement you have templates, but they have their own limitations. Some thing that can be done with preprocessor cannot be done with templates and vice versa. Preprocessor have stringize operator, templates have type-checking and metaprogramming.
My problem is why sometimes the member function SendMessage is called because the code works (most of the time)
If you have SendMessage method in your code (BAD idea on windows platform - clashes with system macro, replace with sendMessage() or use different name, because even namespaces won't help you to avoid omnipresent preprocessor) your method (not SendMessageA/SendMessageW) will be called from *.cpp ONLY if <windows.h> was not included in that *.cpp.
Compiler operates at one file at a time, and has no knowledge of thing that go on in other files, so if there's no <windows.h> #included, your method will be called, because preprocessor won't have any knowledge about SendMessage #define (from <windows.h>). If <windows.h> is included, then ALL occurences of SendMessage will be replaced with SendMessageA/SendMessageW, because preprocessor does its job first.
One possible solution in your situation would be to avoid using naming convention similar to the one in Win API. I.e. make sure that function names don't start with capital letter. That'll solve many problems, but you'll still get minor trouble from min/max macros.
The preprocessor works as a text macro processor. If a macro is defined, all occurrences of the macro are replaced with it's definition.
#define blabla some_real_stuff
struct blabla /* blabla will be replaced with some_real_stuff */
{
void method();
};
int main()
{
some_real_stuff x;
x.method();
}
In the Windows API, there are the two functions SendMessageA and SendMessageW. You will be calling one of these two, depending on what #defines you have in your program.
Are you sure that is not what happens?
Edit: oh wait. Is your #define SendMessage SendMessageA before the definition of the SendMessage member function in your source? If so, the compiler will simply use SendMessageA for the name of the member. Otherwise, your function will be SendMessage, but the rest of your program will call the built in Windows function SendMessageA.
If you have many source files, maybe some of them will know about the #define, while others won't.
My recommendation is to rename the member function to something else and dispense with the #define.

Conflict with DrawText function

I am developing a multi-platform application and in one component I have a class method called DrawText. Unfortunately, I get a linker error (on windows only) saying that there is an unresolved external symbol for a DrawTextW method of this class.
I've seen this before with other methods ending in "Text" where it is looking for either a FooTextW or FooTextA method instead of the FooText method I defined. My assumption is that somewhere in the Windows headers there is a macro definition assigning FooText to FooTextW or FooTextA based on some other definition.
Aside from renaming my function (which is what I did in the past), does anybody have any good ideas for getting around this issue?
Thanks.
Joe
You really only have two choices:
#ifdef DrawText
#undef DrawText
#endif
Or rename your function. Win32 uses macros which have no namespacing or scoping, so you're kinda stuck.
We just re-name our functions.
BTW: It's based on #ifdef UNICODE usually (or _UNICODE or a few other variants).
Yes, this is a real problem with using Windows, and there's no way to turn it off since the headers all look like this:
#ifdef UNICODE
#define GetDlgItemText GetDlgItemTextW
#else
#define GetDlgItemText GetDlgItemTextA
#endif
So you're going to get the symbol defined either way. It would be very nice if you could #define something before #include'ing windows.h that turns this behavior off, but alas none exists.