writing a program using Xamarin.Forms to run across both android and IOS, the following both code versions work on android, However throws a ExecutionEngineException when the second version is ran on IOS but the first one works.
protected static object ReadStruct(BinaryReader reader, Type structType, ChunkHeader chunkHeader)
int size = Marshal.SizeOf(structType);
if (size != chunkHeader.chunkSize) // check the actual size of this chunk object with the expected size from the stream
throw new IOException("Invalid file format, incorrect " + chunkHeader.chunkName + " chunk size (exp.: " + size + ", read: " + chunkHeader.chunkSize + ")");
byte data = reader.ReadBytes(size);
IntPtr buffer = Marshal.AllocHGlobal(size);
Marshal.Copy(data, 0, buffer, size);
// the line that crashes follows this
object structObject = Marshal.PtrToStructure(buffer, structType);
The above code stays the same in both versions.
public struct OvdBChunk
// stuff in here but not important
The above sample works but for this and all future updates i will need to inherit the old versions as stuff may have been updated in newer devices so have been added to but will always keep the old stuff so i changed it to the following
public class OvdBChunk : OvdAChunk
// stuff in here but not important
The structType in part is the part that is changing in the top code snippet.
suggest on here i report it as a bug
Slight bit i missed of origanl post
[StructLayout(LayoutKind.Sequential, Pack = 1)]
is used for public class OvdBChunk : OvdAChunk and public struct OvdBChunk
Hi I've been trying to reproduce that bug based on the informations you gave us and I couldn't.
Could you please provide us:
- A proper test case sample so it's easily reproducible by any member of the team.
- Your XS about information to know the versions of the product you're using.
Created attachment 17076 [details]
Example it works on an ios simulator but not if you put it on an ipad (testing on ipad air 2)
Created attachment 17077 [details]
Any news since i gave you the example to reproduce it?
The fact that the code works in the simulator and does not in the devices makes me believe that it is an issue with the linker. Have you tried using the Preserve attribute (https://developer.xamarin.com/api/type/MonoTouch.Foundation.PreserveAttribute/) in the class you are marshalling? In the example I can only see a use of the type in:
object structObject = Marshal.PtrToStructure(buffer, typeof(StructChunkA));
In my case I was not able to test your application in the simulator (it never launches) but might be due to my setup. Can you please add the attrbute and test it again?
Hey, no joy unfortunately that didn't work
Can you please let me know what is the example app suppose to do, in my case it does not even launch in the simulator, maybe if I know a little more I can "fix" my crash and look into your issue.
It makes a byte array at the start for test data.
When one button is pressed it takes the byte array and makes the designated struct out of it then outputs success on screen.
When the other button is pressed it is suppose to take the byte array and make the designated class out of it then output success on screen, however it fails and outputs the error instead of success.
I have tested the code in the following environments:
Debug - Simulator - Not Link - Works
Debug - Simulator - Link SDK - Works
Debug - iPhone SE - Not Link - Fails
Debug - iPhone SE - Link SDK - Fails
After the testing I'm assigning the bug to the AOT team.
Also, confirmed the bug.
Xamarin.ios currently only supports Marshal.PtrToStructure () etc. on a subset of structures, the struct in your app is probably one which is not supported because it inherits from another structure, the pack directive, etc.
Also, it only works for structures, not classes.
On Desktop, using Marshal.PtrToStructure with an invalid type (a class in this case) throws MarshalDirectiveException.
Can we get this behavior on device as well?
Passing a class type to PtrToStructure is not invalid.
And that's the point, looks like mobile gives a different error than desktop.
I mean Marshal.PtrToStructure () doesn't throw MarshalDirectiveException for class types.
FullAOT should match desktop behavior as close as possible.
Even if that means silently failing.
Can we match the JIT behavior by, IDK, catching the EEE?
So this particular case is not supported because AChunk is a class.
@Zoltan, should we close this bug as invalid?
Probably, its not supported right now.