【问题标题】:C#: Marshal.Copy() access violation converting from IntPtr to floatC#:Marshal.Copy() 访问冲突从 IntPtr 转换为 float
【发布时间】:2013-02-05 22:50:17
【问题描述】:

我正在尝试通过 ReadProcessMemory() 读取内存,然后将读取的值存储在浮点数中(它绝对是内存中的浮点数,我已经使用另一个实用程序对其进行了验证)以供以后参考,但是我尝试过的所有内容( BitConverter、Marshal.Copy() 等)似乎失败了。

我查看了许多示例,但我不确定我没有理解什么。

我编写了一个简短的程序来测试这个概念。我知道完成这项任务的其他技术,但我也遇到了麻烦,所以我现在只关注这个。基本上,我将浮点值中的(已知)字节存储在 4 字节数组中,通过 IntPtr 指向它,然后使用 Marshal.Copy() 尝试从 IntPtr 转换为浮点数:

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”,只是为了获得相同的结果。字节序似乎也不是问题。

任何帮助将不胜感激。

【问题讨论】:

    标签: c# floating-point intptr


    【解决方案1】:

    ((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();
    }
    

    【讨论】:

    • 谢谢,我完全忘记了固定数据。我还没有尝试过(我崩溃并使用了 BitConverter.ToSingle() ),但它看起来应该可以工作。
    【解决方案2】:

    可能是因为 IntPtr 是一个指针,所以在您调用 Marshal.Copy 时它被解释为一个指针,而不是数据。

    请注意,有一种更简单的方法可以从其组成字节构建浮点数:

    float f2 = BitConverter.ToSingle(byteArray, 0);
    

    【讨论】:

    • 我正在使用这个重载:msdn.microsoft.com/en-us/library/a53bd6cz.aspx ... 它不适合这个用途吗?
    • 是的,有点,但它希望第一个参数 ipIntermediate 是指向字节的指针,而不是字节本身。
    • 这实际上并不能回答问题。
    • BitConverter.ToSingle() 确实有效...不确定我第一次尝试时做错了什么。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-25
    • 1970-01-01
    • 1970-01-01
    • 2018-04-16
    • 1970-01-01
    相关资源
    最近更新 更多