# System.Runtime.InteropServices.Marshalling

``` diff
+namespace System.Runtime.InteropServices.Marshalling {
+    [CLSCompliantAttribute(false)]
+    [CustomMarshallerAttribute(typeof(string), MarshalMode.Default, typeof(AnsiStringMarshaller))]
+    [CustomMarshallerAttribute(typeof(string), MarshalMode.ManagedToUnmanagedIn, typeof(AnsiStringMarshaller.ManagedToUnmanagedIn))]
+    public static class AnsiStringMarshaller {
+        public unsafe static string? ConvertToManaged(byte* unmanaged);
+        public unsafe static byte* ConvertToUnmanaged(string? managed);
+        public unsafe static void Free(byte* unmanaged);
+        public ref struct ManagedToUnmanagedIn {
+            public static int BufferSize { get; }
+            public void Free();
+            public void FromManaged(string? managed, Span<byte> buffer);
+            public unsafe byte* ToUnmanaged();
+        }
+    }
+    [CLSCompliantAttribute(false)]
+    [ContiguousCollectionMarshallerAttribute]
+    [CustomMarshallerAttribute(typeof(CustomMarshallerAttribute.GenericPlaceholder[]), MarshalMode.Default, typeof(ArrayMarshaller<,>))]
+    [CustomMarshallerAttribute(typeof(CustomMarshallerAttribute.GenericPlaceholder[]), MarshalMode.ManagedToUnmanagedIn, typeof(ArrayMarshaller<,>.ManagedToUnmanagedIn))]
+    public static class ArrayMarshaller<T, TUnmanagedElement> where TUnmanagedElement : struct {
+        public unsafe static T[]? AllocateContainerForManagedElements(TUnmanagedElement* unmanaged, int numElements);
+        public unsafe static TUnmanagedElement* AllocateContainerForUnmanagedElements(T[]? managed, out int numElements);
+        public unsafe static void Free(TUnmanagedElement* unmanaged);
+        public static Span<T> GetManagedValuesDestination(T[]? managed);
+        public static ReadOnlySpan<T> GetManagedValuesSource(T[]? managed);
+        public unsafe static Span<TUnmanagedElement> GetUnmanagedValuesDestination(TUnmanagedElement* unmanaged, int numElements);
+        public unsafe static ReadOnlySpan<TUnmanagedElement> GetUnmanagedValuesSource(TUnmanagedElement* unmanagedValue, int numElements);
+        public ref struct ManagedToUnmanagedIn {
+            public static int BufferSize { get; }
+            public void Free();
+            public void FromManaged(T[]? array, Span<TUnmanagedElement> buffer);
+            public ReadOnlySpan<T> GetManagedValuesSource();
+            public ref TUnmanagedElement GetPinnableReference();
+            public static ref T GetPinnableReference(T[]? array);
+            public Span<TUnmanagedElement> GetUnmanagedValuesDestination();
+            public unsafe TUnmanagedElement* ToUnmanaged();
+        }
+    }
+    [CLSCompliantAttribute(false)]
+    [CustomMarshallerAttribute(typeof(string), MarshalMode.Default, typeof(BStrStringMarshaller))]
+    [CustomMarshallerAttribute(typeof(string), MarshalMode.ManagedToUnmanagedIn, typeof(BStrStringMarshaller.ManagedToUnmanagedIn))]
+    public static class BStrStringMarshaller {
+        public unsafe static string? ConvertToManaged(ushort* unmanaged);
+        public unsafe static ushort* ConvertToUnmanaged(string? managed);
+        public unsafe static void Free(ushort* unmanaged);
+        public ref struct ManagedToUnmanagedIn {
+            public static int BufferSize { get; }
+            public void Free();
+            public void FromManaged(string? managed, Span<byte> buffer);
+            public unsafe ushort* ToUnmanaged();
+        }
+    }
+    [AttributeUsageAttribute(AttributeTargets.Class | AttributeTargets.Struct)]
+    public sealed class ContiguousCollectionMarshallerAttribute : Attribute {
+        public ContiguousCollectionMarshallerAttribute();
+    }
+    [AttributeUsageAttribute(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple=true)]
+    public sealed class CustomMarshallerAttribute : Attribute {
+        public CustomMarshallerAttribute(Type managedType, MarshalMode marshalMode, Type marshallerType);
+        public Type ManagedType { get; }
+        public Type MarshallerType { get; }
+        public MarshalMode MarshalMode { get; }
+        public struct GenericPlaceholder
+    }
+    public enum MarshalMode {
+        Default = 0,
+        ElementIn = 7,
+        ElementOut = 9,
+        ElementRef = 8,
+        ManagedToUnmanagedIn = 1,
+        ManagedToUnmanagedOut = 3,
+        ManagedToUnmanagedRef = 2,
+        UnmanagedToManagedIn = 4,
+        UnmanagedToManagedOut = 6,
+        UnmanagedToManagedRef = 5,
+    }
+    [AttributeUsageAttribute(AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple=true)]
+    public sealed class MarshalUsingAttribute : Attribute {
+        public const string ReturnsCountValue = "return-value";
+        public MarshalUsingAttribute();
+        public MarshalUsingAttribute(Type nativeType);
+        public int ConstantElementCount { get; set; }
+        public string CountElementName { get; set; }
+        public int ElementIndirectionDepth { get; set; }
+        public Type? NativeType { get; }
+    }
+    [AttributeUsageAttribute(AttributeTargets.Class | AttributeTargets.Delegate | AttributeTargets.Enum | AttributeTargets.Struct)]
+    public sealed class NativeMarshallingAttribute : Attribute {
+        public NativeMarshallingAttribute(Type nativeType);
+        public Type NativeType { get; }
+    }
+    [CLSCompliantAttribute(false)]
+    [ContiguousCollectionMarshallerAttribute]
+    [CustomMarshallerAttribute(typeof(CustomMarshallerAttribute.GenericPlaceholder*[]), MarshalMode.Default, typeof(PointerArrayMarshaller<,>))]
+    [CustomMarshallerAttribute(typeof(CustomMarshallerAttribute.GenericPlaceholder*[]), MarshalMode.ManagedToUnmanagedIn, typeof(PointerArrayMarshaller<,>.ManagedToUnmanagedIn))]
+    public static class PointerArrayMarshaller<T, TUnmanagedElement> where T : struct where TUnmanagedElement : struct {
+        public unsafe static T*[]? AllocateContainerForManagedElements(TUnmanagedElement* unmanaged, int numElements);
+        public unsafe static TUnmanagedElement* AllocateContainerForUnmanagedElements(T*[]? managed, out int numElements);
+        public unsafe static void Free(TUnmanagedElement* unmanaged);
+        public static Span<IntPtr> GetManagedValuesDestination(T*[]? managed);
+        public static ReadOnlySpan<IntPtr> GetManagedValuesSource(T*[]? managed);
+        public unsafe static Span<TUnmanagedElement> GetUnmanagedValuesDestination(TUnmanagedElement* unmanaged, int numElements);
+        public unsafe static ReadOnlySpan<TUnmanagedElement> GetUnmanagedValuesSource(TUnmanagedElement* unmanagedValue, int numElements);
+        public ref struct ManagedToUnmanagedIn {
+            public static int BufferSize { get; }
+            public void Free();
+            public void FromManaged(T*[]? array, Span<TUnmanagedElement> buffer);
+            public ReadOnlySpan<IntPtr> GetManagedValuesSource();
+            public ref TUnmanagedElement GetPinnableReference();
+            public static ref byte GetPinnableReference(T*[]? array);
+            public Span<TUnmanagedElement> GetUnmanagedValuesDestination();
+            public unsafe TUnmanagedElement* ToUnmanaged();
+        }
+    }
+    [CLSCompliantAttribute(false)]
+    [ContiguousCollectionMarshallerAttribute]
+    [CustomMarshallerAttribute(typeof(ReadOnlySpan<>), MarshalMode.ManagedToUnmanagedIn, typeof(ReadOnlySpanMarshaller<,>.ManagedToUnmanagedIn))]
+    [CustomMarshallerAttribute(typeof(ReadOnlySpan<>), MarshalMode.UnmanagedToManagedOut, typeof(ReadOnlySpanMarshaller<,>.UnmanagedToManagedOut))]
+    public static class ReadOnlySpanMarshaller<T, TUnmanagedElement> where TUnmanagedElement : struct {
+        public ref struct ManagedToUnmanagedIn {
+            public static int BufferSize { get; }
+            public void Free();
+            public void FromManaged(ReadOnlySpan<T> managed, Span<TUnmanagedElement> buffer);
+            public ReadOnlySpan<T> GetManagedValuesSource();
+            public ref TUnmanagedElement GetPinnableReference();
+            public static ref T GetPinnableReference(ReadOnlySpan<T> managed);
+            public Span<TUnmanagedElement> GetUnmanagedValuesDestination();
+            public unsafe TUnmanagedElement* ToUnmanaged();
+        }
+        public static class UnmanagedToManagedOut {
+            public unsafe static TUnmanagedElement* AllocateContainerForUnmanagedElements(ReadOnlySpan<T> managed, out int numElements);
+            public static ReadOnlySpan<T> GetManagedValuesSource(ReadOnlySpan<T> managed);
+            public unsafe static Span<TUnmanagedElement> GetUnmanagedValuesDestination(TUnmanagedElement* unmanaged, int numElements);
+        }
+    }
+    [CLSCompliantAttribute(false)]
+    [ContiguousCollectionMarshallerAttribute]
+    [CustomMarshallerAttribute(typeof(Span<>), MarshalMode.Default, typeof(SpanMarshaller<,>))]
+    [CustomMarshallerAttribute(typeof(Span<>), MarshalMode.ManagedToUnmanagedIn, typeof(SpanMarshaller<,>.ManagedToUnmanagedIn))]
+    public static class SpanMarshaller<T, TUnmanagedElement> where TUnmanagedElement : struct {
+        public unsafe static Span<T> AllocateContainerForManagedElements(TUnmanagedElement* unmanaged, int numElements);
+        public unsafe static TUnmanagedElement* AllocateContainerForUnmanagedElements(Span<T> managed, out int numElements);
+        public unsafe static void Free(TUnmanagedElement* unmanaged);
+        public static Span<T> GetManagedValuesDestination(Span<T> managed);
+        public static ReadOnlySpan<T> GetManagedValuesSource(Span<T> managed);
+        public unsafe static Span<TUnmanagedElement> GetUnmanagedValuesDestination(TUnmanagedElement* unmanaged, int numElements);
+        public unsafe static ReadOnlySpan<TUnmanagedElement> GetUnmanagedValuesSource(TUnmanagedElement* unmanaged, int numElements);
+        public ref struct ManagedToUnmanagedIn {
+            public static int BufferSize { get; }
+            public void Free();
+            public void FromManaged(Span<T> managed, Span<TUnmanagedElement> buffer);
+            public ReadOnlySpan<T> GetManagedValuesSource();
+            public ref TUnmanagedElement GetPinnableReference();
+            public static ref T GetPinnableReference(Span<T> managed);
+            public Span<TUnmanagedElement> GetUnmanagedValuesDestination();
+            public unsafe TUnmanagedElement* ToUnmanaged();
+        }
+    }
+    [CLSCompliantAttribute(false)]
+    [CustomMarshallerAttribute(typeof(string), MarshalMode.Default, typeof(Utf16StringMarshaller))]
+    public static class Utf16StringMarshaller {
+        public unsafe static string? ConvertToManaged(ushort* unmanaged);
+        public unsafe static ushort* ConvertToUnmanaged(string? managed);
+        public unsafe static void Free(ushort* unmanaged);
+        public static ref readonly char GetPinnableReference(string? str);
+    }
+    [CLSCompliantAttribute(false)]
+    [CustomMarshallerAttribute(typeof(string), MarshalMode.Default, typeof(Utf8StringMarshaller))]
+    [CustomMarshallerAttribute(typeof(string), MarshalMode.ManagedToUnmanagedIn, typeof(Utf8StringMarshaller.ManagedToUnmanagedIn))]
+    public static class Utf8StringMarshaller {
+        public unsafe static string? ConvertToManaged(byte* unmanaged);
+        public unsafe static byte* ConvertToUnmanaged(string? managed);
+        public unsafe static void Free(byte* unmanaged);
+        public ref struct ManagedToUnmanagedIn {
+            public static int BufferSize { get; }
+            public void Free();
+            public void FromManaged(string? managed, Span<byte> buffer);
+            public unsafe byte* ToUnmanaged();
+        }
+    }
+}
```

