Background and motivation
To address #96525, we can provide a marshaller for ReadOnlySpan<T> for ManagedToUnmanagedOut direction. We have marshallers for UnmanagedToManagedOut and ManagedToUnmanagedIn. This API wasn't created previously due to the assumption that the managed ReadOnlySpan<T> would need to be written to in generated marshaling code, but that isn't strictly necessary for stateful marshallers. This API would allow LibraryImport methods to return ReadOnlySpan<T> without creating a new marshaller or specifying the marshaller type in the method definition.
API Proposal
[System.Runtime.InteropServices.Marshalling.ContiguousCollectionMarshallerAttribute]
[System.Runtime.InteropServices.Marshalling.CustomMarshallerAttribute(typeof(System.ReadOnlySpan<>), System.Runtime.InteropServices.Marshalling.MarshalMode.ManagedToUnmanagedIn, typeof(System.Runtime.InteropServices.Marshalling.ReadOnlySpanMarshaller<,>.ManagedToUnmanagedIn))]
+ [System.Runtime.InteropServices.Marshalling.CustomMarshallerAttribute(typeof(System.ReadOnlySpan<>), System.Runtime.InteropServices.Marshalling.MarshalMode.ManagedToUnmanagedOut, typeof(System.Runtime.InteropServices.Marshalling.ReadOnlySpanMarshaller<,>.ManagedToUnmanagedOut))]
[System.Runtime.InteropServices.Marshalling.CustomMarshallerAttribute(typeof(System.ReadOnlySpan<>), System.Runtime.InteropServices.Marshalling.MarshalMode.UnmanagedToManagedOut, typeof(System.Runtime.InteropServices.Marshalling.ReadOnlySpanMarshaller<,>.UnmanagedToManagedOut))]
public static unsafe class ReadOnlySpanMarshaller<T, TUnmanagedElement> where TUnmanagedElement : unmanaged
{
+ public struct ManagedToUnmanagedOut+ {+ public void FromUnmanaged(TUnmanagedElement* unmanaged) { }+ public ReadOnlySpan<T> ToManaged() { }+ public ReadOnlySpan<TUnmanagedElement> GetUnmanagedValuesSource(int numElements) { }+ public Span<T> GetManagedValuesDestination(int numElements) { }+ public void Free() { }+ }
}API Usage
The API would primarily be used in code generated by the LibraryImport generator to unmarshal a native array into a managed ReadOnlySpan<T> when a method returns a ReadOnlySpan<T> or has an out parameter of type ReadOnlySpan<T>.
[LibraryImport("DllName")][return:MarshalUsing(CountElementName=nameof(length))]publicstaticpartialReadOnlySpan<int>GetRange(intstart,intend,outintlength);Alternative Designs
A workaround is to create a LibraryImport that returns another built-in collection type and create a wrapper that converts the returned collection into a ReadOnlySpan<T>, or use hand-written marshalling for the method.
Risk
Minimal. We already provide marshallers for ReadOnlySpan<T> to pass a parameter in, and we have marshallers for other collections to return a value from a native method, so this is not introducing a new concept.
Background and motivation
To address #96525, we can provide a marshaller for
ReadOnlySpan<T>forManagedToUnmanagedOutdirection. We have marshallers for UnmanagedToManagedOut and ManagedToUnmanagedIn. This API wasn't created previously due to the assumption that the managedReadOnlySpan<T>would need to be written to in generated marshaling code, but that isn't strictly necessary for stateful marshallers. This API would allowLibraryImportmethods to returnReadOnlySpan<T>without creating a new marshaller or specifying the marshaller type in the method definition.API Proposal
API Usage
The API would primarily be used in code generated by the LibraryImport generator to unmarshal a native array into a managed
ReadOnlySpan<T>when a method returns aReadOnlySpan<T>or has anoutparameter of typeReadOnlySpan<T>.Alternative Designs
A workaround is to create a LibraryImport that returns another built-in collection type and create a wrapper that converts the returned collection into a
ReadOnlySpan<T>, or use hand-written marshalling for the method.Risk
Minimal. We already provide marshallers for
ReadOnlySpan<T>to pass a parameter in, and we have marshallers for other collections to return a value from a native method, so this is not introducing a new concept.