I have an application in C# that needs to share some binary data with Python, and I'm planning to use shared memory (memory mapped file). Thus, I need to have the same binary structure on both sides.
I create a struct in C# (ST_Layer
) that has an array of items of another struct (ST_Point
). To access those items I have defined a function getPoint
that will return a pointer to the position of the requested ST_Point
.
using System.Diagnostics;using System.Runtime.InteropServices;using System.Threading;class TestProgram{ [StructLayout(LayoutKind.Explicit, Pack = 8)] public struct ST_Point { [FieldOffset(0)] public double X; [FieldOffset(8)] public double Y; } [StructLayout(LayoutKind.Explicit, Pack = 8)] public unsafe struct ST_Layer { [FieldOffset(0)] public ushort nPoints; [FieldOffset(8)] public double fHeight; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] [FieldOffset(16)] public ST_Point[] Points; public unsafe ST_Point* getPoint(int n) { fixed (ST_Layer* thisPtr = &this) { int ptr = (int)&(thisPtr->Points) + n * ((16 + 3) / 4) * 4; // Sizeof ST_Point 16 return (ST_Point*)ptr; } } } static void Main(string[] args) { unsafe { ST_Layer layer = new ST_Layer(); layer.nPoints = 3; layer.fHeight = 4; layer.getPoint(0)->X = 5; layer.getPoint(3)->Y = 6; for (int i = 0; i < 10; i++) Debug.WriteLine("Data [" + i +"] " + layer.getPoint(i)->X +", " + layer.getPoint(i)->Y +" - "); while (true) Thread.Sleep(50); } }}
I have 2 questions:
- The previous code works if I compile the code for x86, but not for x64 or 'Any CPU' ('System.AccessViolationException' exception in 'layer.getPoint(0)->X'). Is it an expected behaviour? What can I do to solve this exception?
- I'm using the
getPoint
function to access theST_Point
array because I have not seen a better way of accessing it. Is it possible to access it as a normal array (i.e.layer.Points[0].X
)? I can't create the array ofST_Point
(layer.Points = new ST_Point[10]
), as it'll be created outside theST_Layer
, and data will not be passed to Python.
I've seen this and this, but don't know how to access the individual fields of ST_Point
.
Thank you for your help.
[Also, thank you R. Martinho Fernandes for your hint regarding the x86/x64 issue]