MonoTouch 和不安全的浮点

发布于 2024-12-13 15:08:24 字数 1629 浏览 3 评论 0原文

任何人都可以帮助我吗?我有这个“非托管”.NET 代码,它可以在 PC 平台和带有 MonoTouch 设备模拟器的 OSX 上运行。但是当我在 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 设备浮点处理或者它是一个错误。 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 ();
}

非常感谢,

最好的问候, 卡斯帕·沃尔森

Can any one help me. I have this ‘unmanaged’ .NET code, which works on PC Platform and OSX with MonoTouch Device Simulator. But when I run the code on my iPad 2 device, it throws an exception. I have tried to make the code as simple to show the problem.

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

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

On my device, it works when index in &buffer[] is 0, 4 - four bytes aligned as a float32, but fails on all other.

I’m interested to know, is it a bug in the MonoTouch unsafe implementation or is it me, that miss some information about .NET and unsafe code.

I have made a work-around, were I read/write in 4 byte buffer when handle floats, and then copies the data to the correct place in the array, but still it could be nice to know, if I miss understand something about .NET / iPad devices floating point handling or it is a bug. It is no problem with int64 types.

We are using unsafe array handling, because of tcp communication to PLC devices, were we uses arrays of uint8/uint16 and transfer blocks of data for gain higher throughput of data.

If anybody has time, here is a function for test, to try reproduce it:

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

Thanks alot,

Best regards,
Casper Wollesen

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

待天淡蓝洁白时 2024-12-20 15:08:24

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

iOS 设备中使用的 ARM 处理器要求 float 在 4 字节边界上对齐。 x86 架构没有此要求 - 这就是为什么它可以在模拟器、OSX、Windows 上运行...

更新: ARM 结构化对齐常见问题解答

This is not a MonoTouch issue since you would have the same issue in C, C++, ObjectiveC...

The ARM processor, used in iOS devices, requires the float to be aligned on 4 bytes boundaries. The x86 architecture does not have this requirement - which is why it works on the simulator, OSX, Windows...

UPDATE: ARM structured alignment FAQ

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文