当不是4字节alignment时,Monotouch浮点指针会抛出NullReferenceExceptionexception

我面临着一个我无法理解的问题。

在Monotouch中使用C#中的不安全指针时,我在设备(ARM)上得到一个NullReferenceException,但是我不能解释为什么,我们看到一些代码

var rand = new Random(); var buffer = new byte[2 * 1024 * 1024]; rand.NextBytes(buffer); fixed (byte* ptr = buffer) { var ptr2 = ptr + 982515; //This works var bfr = new byte[8]; for (int i = 0; i < 8; i++) bfr[i] = ptr2[i]; var v = BitConverter.ToDouble(bfr, 0); //This throws a NullReferenceException on device var v2 = *(double*)ptr2; Console.WriteLine("v: {0}; v2: {1}", v, v2); } 

它只在设备上崩溃。 任何与ARM结构化alignment有关?

编辑

经过一番研究,我以这样的结局:

浮点值只能从ARM上的4字节alignment地址读取

 static void Main(string[] args) { Test(982512); //Works Test(982516); //Works Test(982515); //Crash on device only } unsafe static void Test(int offset) { var rand = new Random(); var buffer = new byte[2 * 1024 * 1024]; rand.NextBytes(buffer); fixed (byte* ptr = buffer) { var ptr2 = ptr + offset; //Always works var bfr = new byte[8]; for (int i = 0; i < 8; i++) bfr[i] = ptr2[i]; var v = BitConverter.ToDouble(bfr, 0); //Throws a NullReferenceException on device if offset is not 4-byte aligned var v2 = *(double*)ptr2; Console.WriteLine("v: {0}; v2: {1}", v, v2); } } 

任何想法如何绕过这个?

在ARM设备上,只能在4字节alignment的地址处提取浮点值(Single,Double)。

http://www.aleph1.co.uk/chapter-10-arm-structured-alignment-faq

所以解决scheme是这样的:

 static double ReadDouble(byte* ptr, int offset) { var ptr2 = ptr + offset; if ((int)ptr2 % 4 == 0) return *(double*)ptr2; else { var bfr = new byte[8]; for (int i = 0; i < 8; i++) bfr[i] = ptr2[i]; var v = BitConverter.ToDouble(bfr, 0); } }