6

VBA/VB6 でWindows 関数ReadProcessMemorylpBufferを使用していますが、渡すメカニズムをByValに変更しても、関数がこの引数を介して渡された元のオブジェクトの値を変更する理由がわかりません。ドキュメントでは、この引数は参照によって渡される出力として指定されています。引き渡しメカニズムを値渡しに変更することで、元のインスタンスが変更されないようにするべきではありませんか? なぜそうしないのですか?

Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, ByVal lpBaseAddress As Any  _
,byVal lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long

MSDN ReadProcessMemory

4

4 に答える 4

1

CBRF23が正解です。API 関数に文字列引数がある場合、渡す値はバッファーへの long ポインターです。そのポインター値は長整数であり、ポインターの存続期間中、その値は不変です。したがって、値が変更されることはないため、ポインター値のコピーが 2 つあるかどうかは関係ありません。

変更されるのは lpbuffer が指しているバッファ内のメモリであるため、byref または byval を渡すかどうかで値が変更されます。ポインターは、作業を行う場所を示しているだけであり、作業が行われるエンティティではありません。

ポインタは(大まかに)メールアドレスに似ており、ポインターが指すメモリは受信トレイに似ています。概念を視覚化するのに役立つ場合.

于 2015-05-25T19:37:43.550 に答える
1

@ polisha989 「lp」は、型が長いポインターであることを示していると思います。lpBuffer渡すオブジェクトはポインターであるため、値または参照で渡されても違いはないと思います。引数を値で渡しても、システムはポインタのコピーを作成しているだけなので、両方のオブジェクトがメモリ内の同じ値を指しています。したがって、ポインターを ref で渡すか val で渡すかに関係なく、更新された値が表示されるのは、それがポインターの機能だからです。メモリ内の値を指します。ポインターの数に関係なく、それらがすべてメモリ内の同じ場所を指している場合、それらはすべて同じことを示します。

API 呼び出しを行う場合のアドバイスの 1 つは、MSDN を調べるのに時間をかけすぎないことです。関数がどのように機能するかを理解すればするほど、実装が容易になります。正しいオブジェクト タイプを関数に渡していることを確認すると、期待どおりの結果が得られるようになります。

于 2015-05-22T20:14:59.713 に答える
0

As Any宣言が値渡しされることはありません。

型の制限を削除すると、Visual Basic は引数が参照によって渡されると想定します。引数を値で渡すには、プロシージャへの実際の呼び出しに ByVal を含めます。

「決して」の例外として追加したイタリック体に注意してください。

于 2015-05-22T20:38:32.260 に答える