在没有c风格强制转换的情况下,将DWORD_PTR强制转换为class,反之亦然
Cast DWORD_PTR to class and vice versa without c-style cast
根据Herb Sutter的c++编码标准:101规则、指南和最佳实践,程序员应该避免C风格的强制转换:
c风格的强制转换根据上下文具有不同的(通常是危险的)语义,所有这些都隐藏在单个语法之后。用c++风格的强制转换替换C风格的强制转换有助于防止意外错误
我试图将指针p_ctrl
传递给WinAPI回调函数,为此我想使用回调函数的DWORD_PTR参数(下面的示例正在工作,但包含c风格的类型转换,其中注释):
WndCtrls* WndCtrls::Button ( WndCtrls* const p_ctrl, HWND hwnd, RECT const &rc )
{
p_ctrl->ctrl = CreateWindowEx (
0,
L"BUTTON",
p_ctrl->w_classNameButton.c_str (),
WS_VISIBLE | WS_CHILD | BS_OWNERDRAW,
rc.left,
rc.top,
rc.right,
rc.bottom,
hwnd,
0,
(HINSTANCE)GetWindowLongPtr ( hwnd, GWL_HINSTANCE ), // Problematic C-style cast for which I already know workaround
p_ctrl
);
SetWindowSubclass ( p_ctrl->ctrl, WndCtrls::CtrlProc, 0, (DWORD_PTR)p_ctrl ) ) // C-style cast
return p_ctrl;
}
LRESULT CALLBACK WndCtrls::CtrlProc ( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData )
{
WndCtrls* const p_ctrl = (WndCtrls*)dwRefData; // Problematic C-style cast
switch ( message )
{
...
}
return DefSubclassProc ( hwnd, message, wParam, lParam );
}
我已经尝试了动态强制转换,但这给了我错误。根据Sutter的说法,根本不应该使用reinterpret_cast
。
请有一种方法来做这些转换使用c++提供的函数?
Sutter的建议只是建议。它们不是硬性规定;它们只是鼓励你编写更安全、更健壮的代码的建议。
这是advice不起作用的情况之一。
在许多地方,Windows API需要能够传递可能是也可能不是指针的数据。因此,它使用指针大小的整数,使用c风格的强制转换(记住Windows API主要是基于c的)将整数转换为指针。这个是安全的,因为文档要求它是:如果你给Windows一个垃圾指针值,你就违反了该函数的规则!
指针大小的整数的标准C/c++名称是intptr_t
(有符号)和uintptr_t
(无符号)。然而,Windows早于C99和c++ 11(当它们被引入时),所以它使用自己的名称:LONG_PTR
(有符号的)和DWORD_PTR
和ULONG_PTR
(无符号的)。此外,WPARAM
、LPARAM
和LRESULT
也是指针大小的,因为窗口消息经常需要处理指针。
所以继续使用c风格的强制转换或者reinterpret_cast<>
,你喜欢哪个就用哪个。其他类型转换不能工作,因为您需要将整数解释为指针,而其他类型转换不允许您这样做。
无论如何你可能需要这些,因为有其他地方,因为Windows API不仅需要在C中,而且还需要从其他语言中可用,子类化被作为派生结构的第一个元素的结构对象所取代。这在WM_NOTIFY
消息中最为明显,其中所有可能的通知结构都对NMHDR
执行此操作。请记住这一点
- 编译时出错 - 从 DWORD 到 LPCVOID 的转换
- 如何在 c++ 中将 DWORD 转换为 PVOID?
- 三维数组中的C/C++DWORD到BYTE和BYTE到DWORD的转换
- 警告 C4267"参数":从"size_t"转换为"DWORD&quo
- 键入从 DWORD 到 64 位指针的强制转换警告
- 警告 C4267"正在初始化":从'size_t'转换为"DWORD",可能会丢失数据
- 是否可以将 Dword 转换为类型名称
- 从size_t转换为dword,可能会丢失数据
- 有符号浮点变量转换为无符号DWORD
- 无法将DWORD转换为无符号长整型
- 如何将DWORD或char*类型的变量转换为LPCWSTR
- 将十六进制字节值转换为 DWORD (ascii) 格式
- 如何将双精度类型转换为 DWORDLONG 或 DWORD 转换为 DWORDLONG 或 DWORD_PTR 转换为
- 将dword强制转换为字节[4]时出现意外结果(endianity swap?)
- 从"DWORD"到"常量字符*"的转换无效
- 如何将DWORD值转换为空值
- 如何将DWORD转换为char*
- 从无符号长十六进制转换为DWORD
- 如何将DWORD转换为wstring
- 从'double'转换为"DWORD",可能会丢失数据