3

誰かが私を助けることができますか?私はこの「アンマネージド」.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、つまり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 ();
}

どうもありがとう、

よろしく、Casper Wollesen

4

1 に答える 1

4

C、C ++、ObjectiveC ...でも同じ問題が発生するため、これはMonoTouchの問題ではありません。

iOSデバイスで使用されるARMプロセッサでは、floatを4バイト境界に揃える必要があります。x86アーキテクチャにはこの要件はありません。そのため、シミュレータ、OSX、Windowsなどで動作します。

更新: ARM構造化アライメントFAQ

于 2011-11-03T15:41:40.367 に答える