lyra-wasm-scripting-test/guests/csharp/dotnet-guest-test/LyraApi/MarshalUtils.cs

55 lines
1.6 KiB
C#

namespace LyraApi;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
public static class MarshalUtils
{
internal struct AlignmentHelper<T> where T : unmanaged
{
#pragma warning disable CS0649 // Field is never assigned to, and will always have its default value 0
public byte Padding;
public T Target;
#pragma warning restore CS0649 // Field is never assigned to, and will always have its default value 0
}
public static int AlignmentOf<T>() where T : unmanaged
{
return (int)Marshal.OffsetOf<AlignmentHelper<T>>(nameof(AlignmentHelper<T>.Target));
}
public static byte[] GetBytes<T>([DisallowNull] T data)
{
int size = Marshal.SizeOf(data);
byte[] arr = new byte[size];
IntPtr ptr = IntPtr.Zero;
try
{
ptr = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(data, ptr, true);
Marshal.Copy(ptr, arr, 0, size);
}
finally
{
Marshal.FreeHGlobal(ptr);
}
return arr;
}
public static T? FromBytes<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] T>(byte[] data)
{
var ptr = GCHandle.Alloc(data, GCHandleType.Pinned);
try
{
//var res = (T?)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(T));
var res = Marshal.PtrToStructure<T>(ptr.AddrOfPinnedObject());
return res;
}
finally
{
ptr.Free();
}
}
}