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
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
floatto 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