CsWinRT icon indicating copy to clipboard operation
CsWinRT copied to clipboard

Question: Is there any planned support for Memory<> and Span<>?

Open k62o opened this issue 4 years ago • 1 comments

Hi all,

I'm creating an API with IDL 3 that has the following signature (or a similar one): void Process(UInt8[] value);

With C++/WinRT (2.0.210403.2) I have a nice array_view API: void Process(array_view<uint8_t> value); This allows to support many data types with no overhead.

With C#/WinRT (1.2.5) I have an Array API: void Process(byte[] value); This version does not allow us to pass Memory<byte> or Span<byte> that we use in other parts of our application. We may need to create a somewhat useless temporary array.

Do you have plan for Memory<T> and Span<T> support instead of T[]?

Regards, Guillaume

k62o avatar Apr 26 '21 20:04 k62o

At first there could be APIs to interoperate between .NET's spans and memories and WinRT's IBuffer like the following:

namespace System.Runtime.InteropServices.WindowsRuntime;

public static class WindowsRuntimeBufferExtensions
{
+   public static Memory<byte> AsMemory(this IBuffer source);

+   public static Memory<byte> AsMemory(this IBuffer source, uint offset);

+   public static Memory<byte> AsMemory(this IBuffer source, uint offset, int length);

+   public static IBuffer AsWindowsRuntimeBuffer(this Memory<byte> source);

// Gets the underlying IBuffer if the given memory is backed by one.
+   public static bool TryGetWindowsRuntimeBuffer(ReadOnlyMemory<byte> memory, out IBuffer? buffer, out uint offset, out int length);

+   public static void CopyTo(this IBuffer source, Span<byte> destination);

+   public static void CopyTo(this IBuffer source, uint sourceIndex, Span<byte> destination);

+   public static void CopyTo(this ReadOnlySpan<byte> source, IBuffer destination);

+   public static void CopyTo(this ReadOnlySpan<byte> source, IBuffer destination, uint destinationIndex);
}

A next step would be adding Memory<byte> overloads to WinRT APIs that accept IBuffers. If there is a way to mark the IBuffer parameters that their content will not be changed they could be ReadOnlyMemoryies instead.

Passing spans instead of IBuffers is unfortunately impossible; the latter are objects in the heap and the former are ref structs and not allowed to be stored there.

teo-tsirpanis avatar Jan 04 '22 22:01 teo-tsirpanis