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