I’d like to contain WinAPI in a namespace or something. Is this possible without linking issues? Is there some alternative, preferred method if namespaces aren’t possible?
-
9What problems do you have with WinAPI? Link-time name conflicts? Or ugly macros getting in the way? – HolyBlackCat Nov 14 '19 at 22:27
-
1You can declare Windows API functions with a name of your choice (e.g. by using a prefix to move them into a namespace), and use a `#pragma comment(linker, "/alternatename:MySymbol=RealSymbol")` directive, to allow the linker to match your symbols with the exports. – IInspectable Nov 14 '19 at 22:58
-
1@hol: The problem may not be the Windows API, but the `#include
` directive, that pulls in loads of preprocessor macros. If your library contains a symbol named `CreateWindow`, you're inevitably going to run into issues, if you include the `Windows.h` header. – IInspectable Nov 14 '19 at 23:08 -
@IInspectable it is possible to deal with that in some compilers, for instance in MSVC by using `#pragma push_macro("CreateWindow") #undef CreateWindow ... define a custom CreateWindow ... #pragma pop_macro("CreateWindow")` – Remy Lebeau Nov 15 '19 at 01:43
-
Similar with "[How do I avoid name collision with macros defined in Windows header files?](https://stackoverflow.com/questions/2321713/how-do-i-avoid-name-collision-with-macros-defined-in-windows-header-files)"? – Rita Han Nov 15 '19 at 06:01
-
1@rem: I tried that in the past, and found, that it only solves half of the issue. It allows the implementer of a library to introduce a symbol that would otherwise collide with a preprocessor macro defined in the Windows SDK headers. It doesn't help clients of that library, though, if they, too, include the Windows SDK headers. The scheme I illustrated above is more maintainable, for both the implementer and the client of a library. For a real-world use case you can check out the C++/WinRT headers (`base.h`), that ship with the Windows SDK starting at version 17134. – IInspectable Nov 15 '19 at 08:45
-
@IInspectable the only problem I see with that approach is that different compilers use different means to define such alternate mappings for the linker, if they offer such a feature at all. – Remy Lebeau Nov 15 '19 at 13:28
-
@rem: Unfortunately, that's not the only problem. The fact, that the `/alternatename` linker option is undocumented is yet another. I *believe* that it's meant to be used as a means of introducing weak symbols; using it to essentially rename compiler-generated symbols is merely exploiting part of the mechanics. Hopefully, we will get a modularized Windows SDK (wrapper), once C++20 modules arrive, so we no longer have to play tricks. – IInspectable Nov 15 '19 at 13:55
-
1As for the original question, could you please highlight the specific problem you are trying to solve? – IInspectable Nov 15 '19 at 13:57
1 Answers
In c++? not really. The Windows API is a C api so you can't stash it in a namespace. It also uses lots of macros, so the only way to deal with it safely in a generic way is to isolate it.
So, you would have to start by declaring a set of abstract base classes for all the bits of the winapi you wanted to use. They would expose static factory functions or other "clever" methods to get at their functionality: as implementation classes that actually do #include as their final #include statement will then actually implement their functionality in terms of winapi calls.
// shared / clean framework classes
#pragma once
namespace win32 {
class file {
public:
static file* create(string filename);
virtual void read();
virtual void close();
};
}
Some dirty implementation hpp file
#include "win32/file.h"
// this always comes last.
#include <windows.h>
namespace win32 {
class Win32FileImpl : public Win32File
{
HANDLE hf;
public:
static Win32File* create(string filename)
{
auto file = new Win32File();
file->open(filename);
return file;
}
// etc...
}
This would take a long time and I don't think it would be worth the time and effort especially as the resulting framework would be very opinionated in how the classes the classes are allocated, copied and freed.

- 34,244
- 12
- 79
- 148
-
-
While this only serves to illustrate the mechanics, the implementation leaves much to be desired. With C++11's move semantics, there's virtually no reason at all for raw pointers. Simply construct a `Win32File` object with automatic storage duration and `std::move` it out to the caller. Have a look at the WIL's [RAII resource wrappers](https://github.com/Microsoft/wil/wiki/RAII-resource-wrappers) to see, how resource management should be done since C++11. – IInspectable Nov 16 '19 at 07:30
-
Oh god yes. There is so much stuff to implement. Which is really where this approach falls down. As I said - it gets very opinionated: when implementing RAII or some other pattern you tightly constrain the way consumers will invoke classes in your framework: can they simply use "new Something" or do they use factory methods (something::createSomething), or do they always declare SomethingWrapper something();, or is everything wrapped in a std::shared_ptr or similar piece of syntactic noise. – Chris Becke Nov 19 '19 at 07:45