繁体   English   中英

LPVOID上的DWORD类型转换返回什么?

[英]What does type cast of DWORD on LPVOID return?

在C ++中使用类型转换时,我有时会感到困惑,这些回归到底是什么?

LPVOID lpFunction;
DWORD dw = (DWORD)lpFunction; // What does it take from LPVOID?

将会有更多的一般性解释。 谢谢

它不会返回任何有效或有用的内容。

您展示的代码,

LPVOID lpFunction;
DWORD dw = (DWORD)lpFunction; // What does it take from LPVOID?

越野车坏了。

历史上, LPVOID是指向void的远指针(与指向void的近指针PVOID相反)。 远/近指针的区别不再相关,因为我们不再编程为分段架构,所以现在所有LPVOID意味着void* 它相当于PVOID (但是你今天在代码中很少看到后者,因为所有API调用都是远程调用,因此使用LPVOID原型化)。

DWORD类型在历史上是一个无符号的“双字”,在x86上意味着它是32位。 API规范仍然保证DWORD所有支持的体系结构上的无符号32位类型。

这给我们带来了问题。 DWORD是固定大小的类型,用32位表示。 LPVOID是一个指针,指针在不同的体系结构上可以有不同的大小。 这不仅仅是理论上的可移植性问题。 这是一个非常实用的。 在64位架构上(x86-64不仅是Windows支持的平台,而且是当今特别受欢迎的平台), DWORD将是32位,但指针将是64位。 因此,当您将64位指针强制转换为32位整数时,您将不可避免地丢失一些数据。 这就是破坏代码的原因。 它将在64位目标上失败。

如果要强制指向整数类型的指针,则需要使用DWORD_PTR (指针大小的DWORD), INT_PTR (指针的有符号整数表示)或UINT_PTR (指针的无符号整数表示)。 使用任何其他类型来存储指针会使您的代码出错并且损坏。

LPVOID lpFunction = ...;
DWORD_PTR dwpFunction = reinterpret_cast<DWORD_PTR>(lpFunction);
// (dwpFunction now contains an integer representation of the lpFunction pointer)

从更广泛的意义上讲,最好避免将这种类型强制转换为另一种类型的类型。 如果你把它写成C ++风格的演员表,就像我上面所做的那样,你必须编写reinterpret_cast<DWORD>(lpFunction) ,这很明显你做了一些不可移植的东西并且可能不安全。 不可否认,有些情况下这是完全可以的,特别是在编写Windows API时需要它。 这驱动纯粹主义者坚果,但API规范保证它将起作用。 您的代码变得不可移植,但在编写使用Windows特定API的程序时,这几乎不是一个相关问题。 仍然,更喜欢使用C ++风格编写演员表,以便明确你正在做的是一个潜在的问题。 这样,任何查看代码的人都可以检查它以确保API的规则允许您的强制转换,因为编译器不能再这样做了。 演员告诉它关闭并关闭其正常警告。

LPVOID被定义为(Microsoft Windows风格)void长字大小指针”,也就是说,“指向I-not-care-what的指针”。

你现在正在强迫它被视为一个DWORD ...你最好知道(!)占用相同数量的字节,并将该指针的值存储到dw 此变量现在包含以前被视为“内存地址”的内容,但它不再是地址:它是一个双字整数。

顺便说一句,这是一件非常危险的事情,因为它会产生很多“假设”。 它还将指针类型转换为非指针(算术...)类型。 这很容易导致各种难以诊断的错误,并且它消除了编译器为您检测此类错误的潜在能力。

暂无
暂无

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

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