MonoTouch и небезопасная плавающая точка - PullRequest
3 голосов
/ 03 ноября 2011

Может ли кто-нибудь помочь мне.У меня есть этот «неуправляемый» код .NET, который работает на платформе PC и OSX с MonoTouch Device Simulator.Но когда я запускаю код на своем устройстве 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.

Мы используем небезопасную обработку массивов из-за связи 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 ();
}

Большое спасибо,

С уважением, Каспер Воллезен

1 Ответ

4 голосов
/ 03 ноября 2011

Это не проблема MonoTouch, поскольку у вас будет такая же проблема в C, C ++, ObjectiveC ...

Процессору ARM, используемому в устройствах iOS, требуется выравнивание float на 4границы байтов.Архитектура x86 не имеет этого требования - поэтому она работает на симуляторе, OSX, Windows ...

ОБНОВЛЕНИЕ: Структурное выравнивание ARMFAQ

...