55 lines
1.6 KiB
C#
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();
|
|
|
|
}
|
|
}
|
|
} |