dew*_*rde 7 c++ winapi casting
我正试图从我正在处理的一些代码中删除一个c风格的演员,我担心唯一的选择.
原始代码是:
WPARAM param = (WPARAM)(GetDlgItem(IDC_WORKFLOW).m_hWnd);
this->PostMessage(WM_NEXTDLGCTL, param, TRUE);
Run Code Online (Sandbox Code Playgroud)
如果我使用静态强制转换:
WPARAM param = static_cast<WPARAM>(GetDlgItem(IDC_WORKFLOW).m_hWnd);
this->PostMessage(WM_NEXTDLGCTL, param, TRUE);
Run Code Online (Sandbox Code Playgroud)
我收到错误'static_cast':无法从'HWND'转换为'WPARAM',因为底层类型之间没有有效的转换.这给我留下了"魔鬼的选择":
WPARAM param = reinterpret_cast<WPARAM>(GetDlgItem(IDC_WORKFLOW).m_hWnd);
this->PostMessage(WM_NEXTDLGCTL, param, TRUE);
Run Code Online (Sandbox Code Playgroud)
据我所知,如果static_cast是不可能的,并且这与constness无关,那么C-cast无论如何都必须进行reinterpret_cast,这意味着底层代码必须返回,这意味着这是安全的(第3点)在评论中).但是我想在更改代码之前确认一下.
在这个特定情况下,这个演员是否安全,我该如何确认?如果没有,有什么替代方案?
它是安全的,因为WPARAM
定义为:
typedef UINT_PTR WPARAM;
Run Code Online (Sandbox Code Playgroud)
_PTR 后缀表示类型足够大,可以容纳一个指针。
而 HWND 是:
typedef HANDLE HWND;
Run Code Online (Sandbox Code Playgroud)
其中句柄是:
typedef void *HANDLE;
Run Code Online (Sandbox Code Playgroud)
所以 void* 和 UINT_PTR 的大小总是相同的。如果您将其存储在 64 位应用程序中并尝试在 32 位应用程序中读取,那么您会遇到麻烦。
如果您仍然担心进行此类转换是否安全,您可以搜索 Visual Studio 源代码(在 C:\Program Files (x86)\Microsoft Visual Studio 8\ 文件夹中),您会发现很多带有reinterpret_cast<LPARAM>(...)
和的行reinterpret_cast<WPARAM>(...)
。