简体   繁体   English

Windows.h 在 Clang c++20 模块中

[英]Windows.h in Clang c++20 modules

I started working on my first project using c++20 modules, and i chose LLVM Clang as toolset for building.我开始使用 c++20 模块开发我的第一个项目,我选择 LLVM Clang 作为构建工具集。 Problem is that, when i try to include windows.h file, clangs acts as if i didn't.问题是,当我尝试包含 windows.h 文件时,clangs 就像我没有包含一样。 (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.在这种情况下,无论使用 Windows.h 功能,都会抛出错误,即符号不存在。 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.我最近能够为 Visual Studio 2022 17.5(我没有检查任何其他编译器)构建一个Windows C++20 模块,它可以导入到我们公司的代码库中。 In all C++ source files needing Windows API, I then put import Windows;在所有需要Windows API的C++个源文件中,我再import Windows; instead of the traditional #include <Windows.h> .而不是传统的#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.请注意,此方法需要使用 API 函数的全名,如CreateFileW ,而不是传统的宏版本CreateFile ,因为在模块中永远不会导出宏。 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 .未定义的行为#define static是必要的,因为在 Windows API 的某些地方,一些 C 函数被导出为__inline static ,这与export不兼容。

The Windows.macro.h header is a generated file from a simple list of macro names to export in a text file. Windows.macro.h header 是从一个简单的宏名称列表生成的文件,用于导出到文本文件中。 I did not export all macro names (there are tons of them), but only the ones we actually use.我没有导出所有的宏名称(有很多),但只导出了我们实际使用的名称。 The header looks like that: header 看起来像这样:

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.我最近了关于如何将 C 宏常量导出到 C++ 可导出宏常量的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM