I started working on my first project using c++20 modules, and i chose LLVM Clang as toolset for building. Problem is that, when i try to include windows.h file, clangs acts as if i didn't. (This happens ONLY if i have import in the same translation unit)
module;
#include <windows.h>
export module SomeModule;
import Whatever;
export HWND Something(){...}
In this case, whatever uses Windows.h functionality, throws errors, that symbols do not exist. Example:
error: missing '#include <windef.h>'; 'HWND' must be declared before it is used
HWND hwnd;
^
C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\shared\windef.h:39:28: note: declaration here is not visible
DECLARE_HANDLE (HWND);
Why? How to make it work? Help please. Thanks in advance!
I was recently able to build a Windows
C++20 module, for Visual Studio 2022 17.5 (I didn't check any other compiler), that can be imported in our company code base. In all C++ source files needing Windows API, I then put import Windows;
instead of the traditional #include <Windows.h>
. Note that this approach requires to use the full names of API functions like CreateFileW
, not the traditional macro version CreateFile
, since in modules macros are never exported. I see this as an advantage, not polluting the client code with hidden macro definitions that can sometimes create weird compilation errors.
The module definition is a bit of a hack, but seems to work. Here is an abbreviated version, but you get the idea:
module;
#include <string.h>
#include <stdio.h>
#define static // I know it is UB, but it works...
export module Windows;
#pragma warning(disable: 5244)
export
{
#define MICROSOFT_WINDOWS_WINBASE_H_DEFINE_INTERLOCKED_CPLUSPLUS_OVERLOADS 0
// Windows declarations here
#include <winsock2.h>
#include <windows.h>
}
#include "Windows.macro.h"
The undefined behavior #define static
was necessary because in some places of Windows API, some C functions are exported as __inline static
, and this is not compatible with export
.
The Windows.macro.h
header is a generated file from a simple list of macro names to export in a text file. I did not export all macro names (there are tons of them), but only the ones we actually use. The header looks like that:
const auto TEMP_MB_ABORTRETRYIGNORE = MB_ABORTRETRYIGNORE;
#undef MB_ABORTRETRYIGNORE
export const auto MB_ABORTRETRYIGNORE = TEMP_MB_ABORTRETRYIGNORE;
const auto TEMP_MB_ICONSTOP = MB_ICONSTOP;
#undef MB_ICONSTOP
export const auto MB_ICONSTOP = TEMP_MB_ICONSTOP;
const auto TEMP_DATE_SHORTDATE = DATE_SHORTDATE;
#undef DATE_SHORTDATE
export const auto DATE_SHORTDATE = TEMP_DATE_SHORTDATE;
...
I asked recently that question about how to export C macro constants to C++ exportable ones.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.