Marshal / Reinterpret memory between different structs in iJob w/o unsafe context

Hello,

I have two structs that require the same amount of memory. I need to cast an object of struct1 to an object of struct2. However, the structs include arrays. I’m trying to rework my code for DOTS, however, I can’t find a solution that does not require an unsafe context.

This is my latest try:

[StructLayout(LayoutKind.Sequential)]
public struct TestStruct
{
    public int i;
    //[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
    [NativeFixedLength(4)]
    public NativeArray<byte> arr;

    public static implicit operator TestStruct(TestStruct2 myStruct2)
    {
        TestStruct myStruct = new TestStruct();
        IntPtr ptr = Marshal.AllocHGlobal(13);
        Marshal.StructureToPtr(myStruct2, ptr, true);
        myStruct = (TestStruct)Marshal.PtrToStructure(ptr, niiHeader.GetType());
        Marshal.FreeHGlobal(ptr);
        return myStruct;
    }

}



[StructLayout(LayoutKind.Sequential)]
public struct TestStruct2
{
    public int i;
    //[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
    [NativeFixedLength(1)]
    public NativeArray<float> arr;

    public static implicit operator TestStruct2(TestStruct myStruct)
    {
        TestStruct2 myStruct2= new TestStruct2();
        IntPtr ptr = Marshal.AllocHGlobal(13);
        Marshal.StructureToPtr(myStruct, ptr, true);
        myStruct2 = (TestStruct2)Marshal.PtrToStructure(ptr, analHeader.GetType());
        Marshal.FreeHGlobal(ptr);
        return myStruct2;
    }

}

I’m not exactly sure how much extra memory the NativeArray requires for its overhead members (my guess is 5 byte).

When I try to cast between them, I get the error:
MarshalDirectiveException: Type System.Diagnostics.StackTrace which is passed to unmanaged code must have a StructLayout attribute.
(wrapper unknown) TestStruct2.StructureToPtr(object,intptr,bool)
System.Runtime.InteropServices.Marshal.StructureToPtr[T] (T structure, System.IntPtr ptr, System.Boolean fDeleteOld) (at :0)
TestStruct.op_Implicit (TestStruct2 myStruct2)

Am I on the right track or is there any other way to reinterpret-cast between structs that include NativeArrays inside an iJob without requiring an unsafe context?

EDIT: The actual structs in my project include more members (and the arrays don’t line up in memory) in a predetermined order that I cannot change. So NativeArray.Reinterpret will not help my case.

This doesn’t help with your actual problem, but just one thing you need to be very careful of is the size of native containers change when the the safety system is on/off.

A snippet of something similar I had to do a while back.

   internal unsafe struct GridAccessImposter {

#if ENABLE_UNITY_COLLECTIONS_CHECKS
        // UnsafeUtility.SizeOf<ReadOnlyGridAccess>()
        [UsedImplicitly]
        private fixed byte bytes[160];
#else
        private fixed byte bytes[96]; // hashmap/array safeties removed
#endif

        public static implicit operator ReadOnlyGridAccess(GridAccessImposter imposter)
        {
            return UnsafeUtilityEx.As<GridAccessImposter, ReadOnlyGridAccess>(ref imposter);
        }

        public static implicit operator ReadWriteGridAccess(GridAccessImposter imposter)
        {
            return UnsafeUtilityEx.As<GridAccessImposter, ReadWriteGridAccess>(ref imposter);
        }

        public static implicit operator GridAccessImposter(ReadOnlyGridAccess query)
        {
            return UnsafeUtilityEx.As<ReadOnlyGridAccess, GridAccessImposter>(ref query);
        }
    }