我正在尝试通过 ReadProcessMemory() 读取内存,然后将读取的值存储在 float 中(这绝对是内存中的 float ,我已经使用另一个实用程序验证了它)以供以后引用,但是我尝试过的一切( BitConverter、Marshal.Copy() 等)似乎失败。
我看过很多例子,但我不确定我不明白什么。
我编写了一个简短的程序来测试这个概念。我知道完成此任务的其他技术,但我也遇到了麻烦,所以我现在只关注这一点。基本上,我将浮点值中的(已知)字节存储在 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
我运行的是 Windows 7 64 位。我目前的目标是 x86 的构建,但也尝试过“任何 CPU”,但都得到相同的结果。字节序似乎也不是问题。
任何帮助将不胜感激。
最佳答案
((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();
}
关于C#:从 IntPtr 转换为 float 时 Marshal.Copy() 访问冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14718477/