【问题标题】:Getter for Windows handles用于 Windows 句柄的 Getter
【发布时间】:2018-12-14 15:48:13
【问题描述】:

所以我已经学习 C++ 几个月了,我的 IDE 遇到了一个奇怪的事件。 (Jetbrains CLion FTW!)

我的 IDE 可以为成员生成 getter,自动确定类型、是否为 const 以及其他关键字。显然一代并不完美,所以我发现自己通常不会使用这个功能。所以目前我专注于需要使用句柄的 Windows API。因此,当我为句柄(HINSTANCE、HWND、HDC 等)生成 getter 时,会发生一些非常奇怪的事情。

假设我有一个成员定义如下:

HDC m_hDeviceContext;

然后当我的 IDE 生成一个 getter 时,它看起来像这样:

const HDC__* getDeviceContext() const...

我很困惑为什么类型是 HDC__。它是一个指针是有道理的,因此在 winnt.h 中将句柄声明为指针(typedef struct name##__ *name)。

谁能告诉我为什么会发生这种情况?这是我的 IDE 的错误吗,因为每当我看到返回句柄的 getter 示例时,它们通常只是直接返回该句柄类型。

【问题讨论】:

  • 它看起来像你的 IDE 的一个错误。或者也许是某个地方的设置。或者至少是设计缺陷(如果不是设置)。
  • 你可能是对的,CLion 是相当新的。它应该产生什么?
  • 我当然希望它生成HDC getDeviceContext() const {return m_hDeviceContext;}
  • 这更有意义,谢谢。

标签: c++ windows winapi clion


【解决方案1】:

HDC 被定义为不透明的struct 指针的typedef

typedef const struct HDC__ *HDC;

或者在旧的 Windows 版本中作为从 DECLARE_HANDLE(HDC) 扩展的虚拟类型:

typedef struct HDC__{int i;}*HDC;

如果此定义的目的是防止在 typedefed 为 WORDLONGDWORD 的情况下将所有只是整数的不同类型句柄之间混淆。使它们指向不同结构的指针可以防止在不匹配的情况下进行编译。微软已经这样做了至少 20 年。

您的 IDE 可能会查看调试信息而不是解析头文件,并且它不会反转 typedef 的效果。

在 C++ 中,struct 标记在当前命名空间中隐含 typedefed。所以struct HDC__ 也创建了HDC__ 类型。出于某种原因,您的 IDE 假定了这一点。如果您正在编译为 C++,这应该不是问题。如果你用 C 编译,太糟糕了,这个 bug 可能是你的问题中最少的。

【讨论】:

  • 我不认为它在看调试信息,可能只是在扩展typedef。
  • @MatteoItalia:从<winnt.h> 源扩展 typedef 需要大量工作,接近完整的语法 C 或 C++ 解析器,更不用说非标准的 MS 扩展了。如果他们这样做,我会感到惊讶。动态编译源代码和解析调试信息要容易得多。事实上,这些都不需要:在这种情况下,成员定义就是生成包装器所需的全部内容。
  • 我很好奇他们为什么要定义这个结构。指向不完整类型的指针是更严格的实体。你甚至不能给这样的指针加零。
  • @MinorThreat:这种额外的类型安全正是目的。将 HDC 和 HWND 定义为指向不同不透明类型的指针可防止程序员将 HWND 传递到预期 HDC 的位置,等等。
  • 您也不能从一个不完整类型的指针隐式转换为另一种。比如说,如果 HDC__ 和 HBRUSH__ 是不完整的类型,则 DHC__* 不能转换为 HBRUSH__*。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多