2

ReadProcessMemory()を介してメモリを読み取ろうとしているので、後で参照できるように、読み取った値をfloatに格納します(これは間違いなくメモリ内のfloatです。別のユーティリティで検証しました)が、試したことはすべて(BitConverter、Marshal .Copy()など)が失敗するようです。

私はいくつかの例を見てきましたが、何が理解できていないのかよくわかりません。

コンセプトをテストするための短いプログラムを作成しました。私はこのタスクを達成するための他のテクニックを知っていますが、私もそれらに問題を抱えているので、今はこれに焦点を合わせています。基本的に、float値からの(既知の)バイトを4バイトの配列に格納し、IntPtrを介してそれをポイントし、Marshal.Copy()を使用してIntPtrからfloatに変換しようとします。

const int FLOAT_SIZE = 4;
byte[] baSource = new byte[FLOAT_SIZE];
IntPtr ipIntermediate = Marshal.AllocHGlobal(sizeof(float));
float[] faDest = new float[1];

baSource[0] = 0xA7;
baSource[1] = 0x68;
baSource[2] = 0xB9;
baSource[3] = 0x44;

ipIntermediate = ((IntPtr)(baSource[0]));
Marshal.Copy(ipIntermediate, faDest, 0, 1); // causes AccessViolation exception

私はWindows764ビットを実行しています。私は現在、このビルドをx86でターゲットにしていますが、同じ結果を得るために「任意のCPU」も試しました。エンディアンも問題ではないようです。

どんな助けでも大歓迎です。

4

2 に答える 2

2

((IntPtr)(baSource[0]))意味:配列の最初の要素を取得し、それをに変換しIntPtrます。実際に必要なもの:バイト配列の最初の要素のアドレスを取得します。安全でないコードを使用するかGCHandle、これを実現することができます。

const int FLOAT_SIZE = 4;
byte[] baSource = new byte[FLOAT_SIZE];
float[] faDest = new float[1];

baSource[0] = 0xA7;
baSource[1] = 0x68;
baSource[2] = 0xB9;
baSource[3] = 0x44;

var gch = GCHandle.Alloc(baSource, GCHandleType.Pinned);
try
{
    var source = gch.AddrOfPinnedObject();
    Marshal.Copy(source, faDest, 0, 1);
}
finally
{
    gch.Free();
}
于 2013-02-05T23:00:26.210 に答える
0

おそらく、IntPtrはポインターであるため、Marshal.Copyの呼び出しでは、データではなくポインターとして解釈されます。

構成バイトからfloatを作成するもっと簡単な方法があることに注意してください。

float f2 = BitConverter.ToSingle(byteArray, 0);
于 2013-02-05T22:55:46.997 に答える