【问题标题】:C++ Integer to pointer conversionC++ 整数到指针的转换
【发布时间】:2013-07-17 10:50:47
【问题描述】:

所以最近我一直在处理 WinAPI 的 WriteProcessMemoryReadProcessMemory,它们都将 LPVOID 作为第二个参数,这是我们要读取的另一个进程的内存中的实际地址。

考虑到这一点,这个整数到指针的转换是否是正确的 C++ 代码(没有未定义的行为等):

#include <windows.h>
int main()
{
    WriteProcessMemory(/*...*/,
        //want to read from memory address 0x1234 in the target process
        reinterpret_cast<void*>(static_cast<uintptr_t>(0x1234)),
        /*...*/);

    return 0;
}

AFAIK,标准说uintptr_t 是一个整数类型,它能够在不改变指针值的情况下保存指针。由于它是一个整数,我应该能够在其中存储 0x1234。该标准还规定,reinterpret_castuintptr_t 转换为 void* 也会使值保持不变。

【问题讨论】:

    标签: c++ winapi pointers


    【解决方案1】:

    在 Windows 平台上,指针的存储方式与相同的位计数整数类型完全相同。不同之处在于编译器如何解释指针和 int 的值。所以不需要转换。

    将其转换为void */LPVOID 只是为了让编译器满意并在指针位置接受整数值,并且不进行任何转换。在这种情况下,通过 static_cast+reinterpret_cast 是多余的。

    只要确定正确的地址是 0x1234,就不需要转换。只需一个普通的(LPVOID)0x1234(void *)0x1234 即可。

    [编辑] 如 cmets 中所述,常量可能会被截断。然后没有转换可以修复指针值。处理这种情况的一种方法是显式指定常量中使用的类型:

    例如(void *)0x1234567812345678ULL 可以,因为编译器被指示使用 64 位无符号类型。

    【讨论】:

    • 如果我们不考虑我一般使用的是 WinAPI 或 Windows,reinterpret_cast&lt;void*&gt;(static_cast&lt;uintptr_t&gt;(0x1234)) 仍然是将整数转换为 void* 的正确和标准方法吗?
    • 这取决于您如何获得指针值。如果您有一个指针并执行reinterpret_cast&lt;uintptr_t&gt;(static_cast&lt;void *&gt;(p)) 然后打印该值 - 那么是的。
    • 如果我有一个整数i 并做reinterpret_cast&lt;void*&gt;(static_cast&lt;uintptr_t&gt;(i))?
    • @MooingDuck 你是什么意思? uintptr_t 是与 32 位和 64 位平台上的指针具有相同位数的类型。
    • @MooingDuck 我明白你的意思,你是对的 - 0x1234 就像它一样(并且永远是 - 它的常量),但是 0x1234567812345678ULL 需要 ULL(或 MS 的正确后缀编译器用于 64 位常量)。顺便说一句,如果常量被截断,没有复杂的强制转换可以恢复它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-30
    • 1970-01-01
    • 2013-04-14
    • 2016-12-26
    • 1970-01-01
    相关资源
    最近更新 更多