diff --git a/src/Aardvark.Base.IO/Aardvark.Base.IO.csproj b/src/Aardvark.Base.IO/Aardvark.Base.IO.csproj index 79bddd65..6f10d564 100644 --- a/src/Aardvark.Base.IO/Aardvark.Base.IO.csproj +++ b/src/Aardvark.Base.IO/Aardvark.Base.IO.csproj @@ -5,7 +5,7 @@ true 612;1591 true - 8.0 + 9.0 ..\..\bin\Debug diff --git a/src/Aardvark.Base.Tensors.CSharp/Aardvark.Base.Tensors.CSharp.csproj b/src/Aardvark.Base.Tensors.CSharp/Aardvark.Base.Tensors.CSharp.csproj index 2478e6e9..652d3f6b 100644 --- a/src/Aardvark.Base.Tensors.CSharp/Aardvark.Base.Tensors.CSharp.csproj +++ b/src/Aardvark.Base.Tensors.CSharp/Aardvark.Base.Tensors.CSharp.csproj @@ -3,7 +3,7 @@ Library netstandard2.0 - 8.0 + 9.0 true 1591 diff --git a/src/Aardvark.Base/Aardvark.Base.csproj b/src/Aardvark.Base/Aardvark.Base.csproj index fa6eaba3..af6d61c0 100644 --- a/src/Aardvark.Base/Aardvark.Base.csproj +++ b/src/Aardvark.Base/Aardvark.Base.csproj @@ -2,7 +2,7 @@ net8.0;netstandard2.0 - 8.0 + 9.0 true diff --git a/src/Aardvark.Base/Extensions/ArrayExtensions.cs b/src/Aardvark.Base/Extensions/ArrayExtensions.cs index 3b45a251..a27064b5 100644 --- a/src/Aardvark.Base/Extensions/ArrayExtensions.cs +++ b/src/Aardvark.Base/Extensions/ArrayExtensions.cs @@ -2265,7 +2265,7 @@ public static void CopyTo(this Array input, int offset, int length, IntPtr targe try { var typeSize = input.GetType().GetElementType().GetCLRSize(); - var dataSize = input.Length * typeSize; + var dataSize = length * typeSize; unsafe { @@ -2281,14 +2281,10 @@ public static void CopyTo(this Array input, int offset, int length, IntPtr targe } public static void CopyTo(this Array input, int length, IntPtr target) - { - CopyTo(input, 0, length, target); - } + => CopyTo(input, 0, length, target); public static void CopyTo(this Array input, IntPtr target) - { - CopyTo(input, 0, input.Length, target); - } + => CopyTo(input, 0, input.Length, target); public static void CopyTo(this IntPtr input, Array target, int offset, int length) { @@ -2297,7 +2293,7 @@ public static void CopyTo(this IntPtr input, Array target, int offset, int lengt try { var typeSize = target.GetType().GetElementType().GetCLRSize(); - var dataSize = target.Length * typeSize; + var dataSize = length * typeSize; unsafe { @@ -2312,15 +2308,10 @@ public static void CopyTo(this IntPtr input, Array target, int offset, int lengt } public static void CopyTo(this IntPtr input, Array target, int length) - { - CopyTo(input, target, 0, length); - } + => CopyTo(input, target, 0, length); public static void CopyTo(this IntPtr input, Array target) - { - CopyTo(input, target, target.Length); - } - + => CopyTo(input, target, target.Length); public static void CopyTo(this IntPtr input, IntPtr target, int size) { diff --git a/src/Aardvark.Base/Extensions/UnsafeCoerce.cs b/src/Aardvark.Base/Extensions/UnsafeCoerce.cs index b592a006..fc207aca 100644 --- a/src/Aardvark.Base/Extensions/UnsafeCoerce.cs +++ b/src/Aardvark.Base/Extensions/UnsafeCoerce.cs @@ -1,12 +1,31 @@ using System; +using System.Collections.Concurrent; +using System.Reflection; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace Aardvark.Base { public static class ArrayUnsafeCoerceExtensions { + private static readonly MethodInfo unsafeSizeOfMeth = typeof(Unsafe).GetMethod(nameof(Unsafe.SizeOf), BindingFlags.Public | BindingFlags.Static); + + private static readonly ConcurrentDictionary unsafeTypeSizes = new(); + + /// + /// Returns the managed size of the given type. + /// + public static int GetCLRSize(this Type t) + { + return unsafeTypeSizes.GetOrAdd(t, t => + { + var mi = unsafeSizeOfMeth.MakeGenericMethod(t); + return (int)mi.Invoke(null, null); + }); + } + #region UnsafeCoerce - + [Obsolete("breaks net8.0+")] public static IntPtr GetTypeIdUncached() where T : struct @@ -32,14 +51,6 @@ private static IntPtr GetTypeId() return typeId; } - public static int GetCLRSize(this Type t) - { - // TODO: somehow make use of sizeof operator -> requires compile time type -> cannot use ILGenerator in .net standard - if (t == typeof(char)) return 2; // Marshal.SizeOf = 1 - if (t == typeof(bool)) return 1; // Marshal.SizeOf = 4 - return Marshal.SizeOf(t); - } - [Obsolete("breaks net8.0+")] internal static TR[] UnsafeCoerce(this Array input, IntPtr targetId) where TR : struct diff --git a/src/Tests/Aardvark.Base.FSharp.Tests/Aardvark.Base.FSharp.Tests.fsproj b/src/Tests/Aardvark.Base.FSharp.Tests/Aardvark.Base.FSharp.Tests.fsproj index 348ec2d9..92ab4f93 100644 --- a/src/Tests/Aardvark.Base.FSharp.Tests/Aardvark.Base.FSharp.Tests.fsproj +++ b/src/Tests/Aardvark.Base.FSharp.Tests/Aardvark.Base.FSharp.Tests.fsproj @@ -34,6 +34,7 @@ + diff --git a/src/Tests/Aardvark.Base.FSharp.Tests/SizeOfTests.fs b/src/Tests/Aardvark.Base.FSharp.Tests/SizeOfTests.fs new file mode 100644 index 00000000..88b7c633 --- /dev/null +++ b/src/Tests/Aardvark.Base.FSharp.Tests/SizeOfTests.fs @@ -0,0 +1,25 @@ +namespace Aardvark.Base.FSharp.Tests + +open Aardvark.Base +open System.Runtime.InteropServices + +open FsUnit +open NUnit.Framework + +module SizeOfTests = + + [] + type MyStruct = + val A : bool + val B : bool + val C : char + + [] + let ``[GetCLRSize] Primitive types``() = + typeof.GetCLRSize() |> should equal 8 + typeof.GetCLRSize() |> should equal 1 + typeof.GetCLRSize() |> should equal 2 + + [] + let ``[GetCLRSize] Struct``() = + typeof.GetCLRSize() |> should equal 4