3

そのため、最近、私は WinAPI を扱っておりWriteProcessMemoryReadProcessMemoryどちらもLPVOID2 番目の引数として、読み取りたい別のプロセスのメモリ内の実際のアドレスを受け取ります。

それを考慮すると、この整数からポインターへの変換は正しい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;
}

私の知る限り、標準でuintptr_tは、ポインターの値を変更せずにポインターを保持できる整数型であると言われています。整数なので、0x1234 を格納できるはずです。標準では、reinterpret_castan uintptr_tto avoid*を使用しても値が変更されないことも示されています。

4

1 に答える 1

1

Windows プラットフォームでは、ポインターは同じビット カウント整数型とまったく同じ方法で格納されます。違いは、コンパイラがポインターと int の値を解釈する方法です。したがって、変換は必要ありません。

void */へのキャストLPVOIDは、コンパイラを満足させ、ポインターの場所で整数値を受け入れるためのものであり、変換は行われません。この場合、 static_cast+reinterpret_cast を実行するのはやり過ぎです。

正しいアドレスが 0x1234 であることが確実である限り、変換は必要ありません。プレーン(LPVOID)0x1234または(void *)0x1234すべきです。

[編集] コメントで指摘されているように、定数は切り捨てられる場合があります。その場合、ポインター値を修正する変換はありません。これを処理する方法は、定数で使用される型を明示的に指定することです。

たとえば(void *)0x1234567812345678ULL、コンパイラは 64 ビットの符号なし型を使用するように指示されているため、問題ありません。

于 2013-07-17T00:04:44.930 に答える