c++ - 将此 c-cast 更改为 reinterpret_cast 是否安全?

标签 c++ winapi casting reinterpret-cast

我正在尝试从我正在处理的一些代码中删除 c 风格的强制转换,但我担心唯一的选择。

原代码为:

WPARAM param = (WPARAM)(GetDlgItem(IDC_WORKFLOW).m_hWnd);
this->PostMessage(WM_NEXTDLGCTL, param, TRUE);

如果我使用静态转换:

WPARAM param = static_cast<WPARAM>(GetDlgItem(IDC_WORKFLOW).m_hWnd);
this->PostMessage(WM_NEXTDLGCTL, param, TRUE);

我收到错误“static_cast”:无法从“HWND”转换为“WPARAM”,因为基础类型之间没有有效的转换。这给我留下了“魔鬼的选择”:

WPARAM param = reinterpret_cast<WPARAM>(GetDlgItem(IDC_WORKFLOW).m_hWnd);
this->PostMessage(WM_NEXTDLGCTL, param, TRUE);

据我了解,如果 static_cast 是不可能的,并且这与常量无关,则 C-cast 无论如何都必须执行 reinterpret_cast,这意味着底层代码必须回退,which means this is safe (备注中的第 3 点)。但我想在更改代码之前确认这一点。

在此特定实例中此转换是否安全,我如何确认这一点?如果不能,还有什么选择?

最佳答案

这是安全的,因为WPARAM定义为:

typedef UINT_PTR            WPARAM;

和 _PTR 后缀表示该类型大到足以容纳一个指针。

而 HWND 是:

 typedef HANDLE HWND;

句柄在哪里:

typedef void *HANDLE;

所以 void* 和 UINT_PTR 的大小总是相同的。如果您将它存储在 64 位应用程序中并尝试在 32 位应用程序中读取,那么您会遇到麻烦。

如果您仍然担心进行此类转换是否安全,您可以搜索 Visual Studio 源代码(在 C:\Program Files (x86)\Microsoft Visual Studio 8\文件夹中),您会发现很多行reinterpret_cast<LPARAM>(...)reinterpret_cast<WPARAM>(...) .

关于c++ - 将此 c-cast 更改为 reinterpret_cast 是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21753538/

相关文章:

c++ - 当模板参数是 bidirectional_iterator 时如何启用模板类特化?

c++ - 开关头中的变量声明?

winapi - 如何使用 shell 扩展 dll C++ 在上下文菜单之间添加分隔符

c++ - 如何获取 LIST 命令的响应消息(来自 CFTPConnection)

visual-studio-2008 - 在Visual Studio 2008中未正确设置WindowsSdkDir?

c - 将 double 转换为 float 时会发生什么?

c++ - FFMPEG I/O 的自定义读取功能

c++ - 使用按位运算符消除 IF 语句

model-view-controller - 将 ActionScript 对象转换为模型

c# - 如何转换为给定类型?