MonoTouch和不安全的浮点

时间:2011-11-03 14:25:07

标签: xamarin.ios arm unmanaged unsafe memory-alignment

任何人都可以帮助我。我有这个'非托管'.NET代码,可以在PC平台和OSX上使用MonoTouch设备模拟器。但是当我在iPad 2设备上运行代码时,它会引发异常。我试图使代码变得简单,以显示问题。

var buffer = new byte[ 8 ]; // Space for 2 float32.
float value = 123f;                                     

fixed (byte* ptr = &buffer[1])
{
    var fp = (float*)ptr;
    *fp = value;
}   

在我的设备上,它在& buffer []中的索引为0,4 - 四个字节作为float32对齐时有效,但在其他所有字符串上都失败。

我很想知道,这是MonoTouch不安全实现中的一个错误,还是我,它错过了一些关于.NET和不安全代码的信息。

我做了一个解决方法,当我在句柄浮动时读取/写入4字节缓冲区,然后将数据复制到数组中的正确位置,但是如果我错过了解它仍然可以很好关于.NET / iPad设备浮点处理或者它是一个bug。 int64类型没有问题。

我们正在使用不安全的数组处理,因为与PLC设备的tcp通信,我们使用uint8 / uint16数组并传输数据块以获得更高的数据吞吐量。

如果有人有时间,这里有一个测试功能,尝试重现它:

BugTest(8); // Returns “S0,S1,S2,S3,S4,S5,S6,S7,” On my pc and mac with iPad simulator.
BugTest(8); // Returns “S0,F1,F2,F3,S4,F5,F6,F7,” On my iPad device.


unsafe string BugTest(int numberOfIndexesTest)
{
    var testResult = new StringBuilder();
    var buffer = new byte[ numberOfIndexesTest + sizeof(float)];    
    float value = 123f;                                     

    for(var index=0; index<numberOfIndexesTest;index++)
    {
        try
        {
            fixed (byte* ptr = &buffer[index])
            {
                var fp = (float*)ptr;
                *fp = value;

                testResult.AppendLine(string.Format("S{0},", index));
            }   
        }
        catch(Exception e)
        {
            testResult.AppendLine(string.Format("F{0},", index));
        }
    }

    return testResult.ToString ();
}

非常感谢,

祝你好运, Casper Wollesen

1 个答案:

答案 0 :(得分:4)

这不是MonoTouch问题,因为您在C,C ++,ObjectiveC中会遇到同样的问题......

在iOS设备中使用的ARM处理器要求float在4字节边界上对齐。 x86 架构没有这个要求 - 这就是它在模拟器,OSX,Windows上工作的原因......

更新: ARM structured alignment FAQ