From 0d4b0e7c4cd9339c6c1c3bab0e1936ce3ed0314f Mon Sep 17 00:00:00 2001 From: Elinor Fung Date: Tue, 12 Apr 2022 18:09:58 -0700 Subject: [PATCH 1/2] Expose ArrayMarshaller and PointerArrayMarshaller --- eng/generators.targets | 10 - .../InteropServices/ArrayMarshaller.cs | 168 ----------------- .../System.Private.CoreLib.Shared.projitems | 2 + .../InteropServices/ArrayMarshaller.cs | 166 +++++++++++++++++ .../InteropServices/PointerArrayMarshaller.cs | 174 ++++++++++++++++++ .../MarshallingAttributeInfo.cs | 4 +- .../TypeNames.cs | 4 +- .../ref/System.Runtime.InteropServices.cs | 48 ++++- .../Ancillary.Interop.csproj | 3 - 9 files changed, 391 insertions(+), 188 deletions(-) delete mode 100644 src/libraries/Common/src/System/Runtime/InteropServices/ArrayMarshaller.cs create mode 100644 src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ArrayMarshaller.cs create mode 100644 src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/PointerArrayMarshaller.cs diff --git a/eng/generators.targets b/eng/generators.targets index 5d806b69a18079..f830dbd52f2062 100644 --- a/eng/generators.targets +++ b/eng/generators.targets @@ -50,16 +50,6 @@ Include="$(CoreLibSharedDir)System\Runtime\InteropServices\LibraryImportAttribute.cs" /> - - - diff --git a/src/libraries/Common/src/System/Runtime/InteropServices/ArrayMarshaller.cs b/src/libraries/Common/src/System/Runtime/InteropServices/ArrayMarshaller.cs deleted file mode 100644 index f5c5277a7d373d..00000000000000 --- a/src/libraries/Common/src/System/Runtime/InteropServices/ArrayMarshaller.cs +++ /dev/null @@ -1,168 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -// -// Types in this file are used for generated p/invokes (docs/design/features/source-generator-pinvokes.md). -// - -using System.Diagnostics; -using System.Runtime.CompilerServices; - -namespace System.Runtime.InteropServices.GeneratedMarshalling -{ - // Stack-alloc threshold set to 256 bytes to enable small arrays to be passed on the stack. - // Number kept small to ensure that P/Invokes with a lot of array parameters doesn't - // blow the stack since this is a new optimization in the code-generated interop. - [CustomTypeMarshaller(typeof(CustomTypeMarshallerAttribute.GenericPlaceholder[]), CustomTypeMarshallerKind.LinearCollection, Features = CustomTypeMarshallerFeatures.UnmanagedResources | CustomTypeMarshallerFeatures.CallerAllocatedBuffer | CustomTypeMarshallerFeatures.TwoStageMarshalling, BufferSize = 0x200)] -#if LIBRARYIMPORT_GENERATOR_TEST - public -#else - internal -#endif - unsafe ref struct ArrayMarshaller - { - private T[]? _managedArray; - private readonly int _sizeOfNativeElement; - private IntPtr _allocatedMemory; - - public ArrayMarshaller(int sizeOfNativeElement) - : this() - { - _sizeOfNativeElement = sizeOfNativeElement; - } - - public ArrayMarshaller(T[]? managed, int sizeOfNativeElement) - :this(managed, Span.Empty, sizeOfNativeElement) - { - } - - public ArrayMarshaller(T[]? managed, Span stackSpace, int sizeOfNativeElement) - { - _allocatedMemory = default; - _sizeOfNativeElement = sizeOfNativeElement; - if (managed is null) - { - _managedArray = null; - NativeValueStorage = default; - return; - } - _managedArray = managed; - // Always allocate at least one byte when the array is zero-length. - int spaceToAllocate = Math.Max(managed.Length * _sizeOfNativeElement, 1); - if (spaceToAllocate <= stackSpace.Length) - { - NativeValueStorage = stackSpace[0..spaceToAllocate]; - } - else - { - _allocatedMemory = Marshal.AllocCoTaskMem(spaceToAllocate); - NativeValueStorage = new Span((void*)_allocatedMemory, spaceToAllocate); - } - } - - public ReadOnlySpan GetManagedValuesSource() => _managedArray; - public Span GetManagedValuesDestination(int length) => _allocatedMemory == IntPtr.Zero ? null : _managedArray = new T[length]; - public Span GetNativeValuesDestination() => NativeValueStorage; - - public ReadOnlySpan GetNativeValuesSource(int length) - { - return _allocatedMemory == IntPtr.Zero ? default : NativeValueStorage = new Span((void*)_allocatedMemory, length * _sizeOfNativeElement); - } - private Span NativeValueStorage { get; set; } - - public ref byte GetPinnableReference() => ref MemoryMarshal.GetReference(NativeValueStorage); - - - public byte* ToNativeValue() => (byte*)Unsafe.AsPointer(ref GetPinnableReference()); - - public void FromNativeValue(byte* value) - { - _allocatedMemory = (IntPtr)value; - } - - public T[]? ToManaged() => _managedArray; - - public void FreeNative() - { - Marshal.FreeCoTaskMem(_allocatedMemory); - } - } - - // Stack-alloc threshold set to 256 bytes to enable small arrays to be passed on the stack. - // Number kept small to ensure that P/Invokes with a lot of array parameters doesn't - // blow the stack since this is a new optimization in the code-generated interop. - [CustomTypeMarshaller(typeof(CustomTypeMarshallerAttribute.GenericPlaceholder*[]), CustomTypeMarshallerKind.LinearCollection, Features = CustomTypeMarshallerFeatures.UnmanagedResources | CustomTypeMarshallerFeatures.CallerAllocatedBuffer | CustomTypeMarshallerFeatures.TwoStageMarshalling, BufferSize = 0x200)] -#if LIBRARYIMPORT_GENERATOR_TEST - public -#else - internal -#endif - unsafe ref struct PtrArrayMarshaller where T : unmanaged - { - private T*[]? _managedArray; - private readonly int _sizeOfNativeElement; - private IntPtr _allocatedMemory; - - public PtrArrayMarshaller(int sizeOfNativeElement) - : this() - { - _sizeOfNativeElement = sizeOfNativeElement; - } - - public PtrArrayMarshaller(T*[]? managed, int sizeOfNativeElement) - :this(managed, Span.Empty, sizeOfNativeElement) - { - } - - public PtrArrayMarshaller(T*[]? managed, Span stackSpace, int sizeOfNativeElement) - { - _allocatedMemory = default; - _sizeOfNativeElement = sizeOfNativeElement; - if (managed is null) - { - _managedArray = null; - NativeValueStorage = default; - return; - } - _managedArray = managed; - // Always allocate at least one byte when the array is zero-length. - int spaceToAllocate = Math.Max(managed.Length * _sizeOfNativeElement, 1); - if (spaceToAllocate <= stackSpace.Length) - { - NativeValueStorage = stackSpace[0..spaceToAllocate]; - } - else - { - _allocatedMemory = Marshal.AllocCoTaskMem(spaceToAllocate); - NativeValueStorage = new Span((void*)_allocatedMemory, spaceToAllocate); - } - } - - public ReadOnlySpan GetManagedValuesSource() => Unsafe.As(_managedArray); - public Span GetManagedValuesDestination(int length) => _allocatedMemory == IntPtr.Zero ? null : Unsafe.As(_managedArray = new T*[length]); - public Span GetNativeValuesDestination() => NativeValueStorage; - - public ReadOnlySpan GetNativeValuesSource(int length) - { - return _allocatedMemory == IntPtr.Zero ? default : NativeValueStorage = new Span((void*)_allocatedMemory, length * _sizeOfNativeElement); - } - private Span NativeValueStorage { get; set; } - - public ref byte GetPinnableReference() => ref MemoryMarshal.GetReference(NativeValueStorage); - public byte* ToNativeValue() => (byte*)Unsafe.AsPointer(ref GetPinnableReference()); - - public void FromNativeValue(byte* value) - { - _allocatedMemory = (IntPtr)value; - } - - public T*[]? ToManaged() => _managedArray; - - public void FreeNative() - { - Marshal.FreeCoTaskMem(_allocatedMemory); - } - } -} diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index b76fee8bac73e3..985fcd2e870801 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -789,6 +789,7 @@ + @@ -872,6 +873,7 @@ + diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ArrayMarshaller.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ArrayMarshaller.cs new file mode 100644 index 00000000000000..4282b96f63055c --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ArrayMarshaller.cs @@ -0,0 +1,166 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics; +using System.Runtime.CompilerServices; + +namespace System.Runtime.InteropServices +{ + /// + /// Marshaller for arrays + /// + /// Array element type + [CLSCompliant(false)] + [CustomTypeMarshaller(typeof(CustomTypeMarshallerAttribute.GenericPlaceholder[]), + CustomTypeMarshallerKind.LinearCollection, BufferSize = 0x200, + Features = CustomTypeMarshallerFeatures.UnmanagedResources | CustomTypeMarshallerFeatures.CallerAllocatedBuffer | CustomTypeMarshallerFeatures.TwoStageMarshalling)] + public unsafe ref struct ArrayMarshaller + { + private readonly int _sizeOfNativeElement; + + private T[]? _managedArray; + private IntPtr _allocatedMemory; + private Span _span; + + /// + /// Initializes a new instance of the . + /// + /// Size of the native element in bytes. + public ArrayMarshaller(int sizeOfNativeElement) + : this() + { + _sizeOfNativeElement = sizeOfNativeElement; + } + + /// + /// Initializes a new instance of the . + /// + /// Array to be marshalled. + /// Size of the native element in bytes. + public ArrayMarshaller(T[]? array, int sizeOfNativeElement) + : this(array, Span.Empty, sizeOfNativeElement) + { } + + /// + /// Initializes a new instance of the . + /// + /// Array to be marshalled. + /// Buffer that may be used for marshalling. + /// Size of the native element in bytes. + /// + /// The must not be movable - that is, it should not be + /// on the managed heap or it should be pinned. + /// + /// + public ArrayMarshaller(T[]? array, Span buffer, int sizeOfNativeElement) + { + _allocatedMemory = default; + _sizeOfNativeElement = sizeOfNativeElement; + if (array is null) + { + _managedArray = null; + _span = default; + return; + } + + _managedArray = array; + + // Always allocate at least one byte when the array is zero-length. + int spaceToAllocate = Math.Max(array.Length * _sizeOfNativeElement, 1); + if (spaceToAllocate <= buffer.Length) + { + _span = buffer[0..spaceToAllocate]; + } + else + { + _allocatedMemory = Marshal.AllocCoTaskMem(spaceToAllocate); + _span = new Span((void*)_allocatedMemory, spaceToAllocate); + } + } + + /// + /// Gets a span that points to the memory where the managed values of the array are stored. + /// + /// Span over managed values of the array. + /// + /// + /// + public ReadOnlySpan GetManagedValuesSource() => _managedArray; + + /// + /// Gets a span that points to the memory where the unmarshalled managed values of the array should be stored. + /// + /// Length of the array. + /// Span where managed values of the array should be stored. + /// + /// + /// + public Span GetManagedValuesDestination(int length) => _allocatedMemory == IntPtr.Zero ? null : _managedArray = new T[length]; + + /// + /// Returns a span that points to the memory where the native values of the array are stored after the native call. + /// + /// Length of the array. + /// Span over the native values of the array. + /// + /// + /// + public ReadOnlySpan GetNativeValuesSource(int length) + { + return _allocatedMemory == IntPtr.Zero ? default : _span = new Span((void*)_allocatedMemory, length * _sizeOfNativeElement); + } + + /// + /// Returns a span that points to the memory where the native values of the array should be stored. + /// + /// Span where native values of the array should be stored. + /// + /// + /// + public Span GetNativeValuesDestination() => _span; + + /// + /// Returns a reference to the marshalled array. + /// + public ref byte GetPinnableReference() => ref MemoryMarshal.GetReference(_span); + + /// + /// Returns the native value representing the array. + /// + /// + /// + /// + public byte* ToNativeValue() => (byte*)Unsafe.AsPointer(ref GetPinnableReference()); + + /// + /// Sets the native value representing the array. + /// + /// The native value. + /// + /// + /// + public void FromNativeValue(byte* value) + { + _allocatedMemory = (IntPtr)value; + } + + /// + /// Returns the managed array. + /// + /// + /// + /// + public T[]? ToManaged() => _managedArray; + + /// + /// Frees native resources. + /// + /// + /// + /// + public void FreeNative() + { + Marshal.FreeCoTaskMem(_allocatedMemory); + } + } +} diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/PointerArrayMarshaller.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/PointerArrayMarshaller.cs new file mode 100644 index 00000000000000..0d998b834a1ec7 --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/PointerArrayMarshaller.cs @@ -0,0 +1,174 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics; +using System.Runtime.CompilerServices; + +namespace System.Runtime.InteropServices +{ + /// + /// Marshaller for arrays of pointers + /// + /// Array element pointer type + [CLSCompliant(false)] + [CustomTypeMarshaller(typeof(CustomTypeMarshallerAttribute.GenericPlaceholder*[]), + CustomTypeMarshallerKind.LinearCollection, BufferSize = 0x200, + Features = CustomTypeMarshallerFeatures.UnmanagedResources | CustomTypeMarshallerFeatures.CallerAllocatedBuffer | CustomTypeMarshallerFeatures.TwoStageMarshalling)] + public unsafe ref struct PointerArrayMarshaller where T : unmanaged + { + private readonly int _sizeOfNativeElement; + + private T*[]? _managedArray; + private IntPtr _allocatedMemory; + private Span _span; + + /// + /// Initializes a new instance of the . + /// + /// Size of the native element in bytes. + public PointerArrayMarshaller(int sizeOfNativeElement) + : this() + { + _sizeOfNativeElement = sizeOfNativeElement; + } + + /// + /// Initializes a new instance of the . + /// + /// Array to be marshalled. + /// Size of the native element in bytes. + public PointerArrayMarshaller(T*[]? array, int sizeOfNativeElement) + : this(array, Span.Empty, sizeOfNativeElement) + { } + + /// + /// Initializes a new instance of the . + /// + /// Array to be marshalled. + /// Buffer that may be used for marshalling. + /// Size of the native element in bytes. + /// + /// The must not be movable - that is, it should not be + /// on the managed heap or it should be pinned. + /// + /// + public PointerArrayMarshaller(T*[]? array, Span buffer, int sizeOfNativeElement) + { + _allocatedMemory = default; + _sizeOfNativeElement = sizeOfNativeElement; + if (array is null) + { + _managedArray = null; + _span = default; + return; + } + + _managedArray = array; + + // Always allocate at least one byte when the array is zero-length. + int spaceToAllocate = Math.Max(array.Length * _sizeOfNativeElement, 1); + if (spaceToAllocate <= buffer.Length) + { + _span = buffer[0..spaceToAllocate]; + } + else + { + _allocatedMemory = Marshal.AllocCoTaskMem(spaceToAllocate); + _span = new Span((void*)_allocatedMemory, spaceToAllocate); + } + } + + /// + /// Gets a span that points to the memory where the managed values of the array are stored. + /// + /// Span over managed values of the array. + /// + /// + /// + public ReadOnlySpan GetManagedValuesSource() => Unsafe.As(_managedArray); + + /// + /// Gets a span that points to the memory where the unmarshalled managed values of the array should be stored. + /// + /// Length of the array. + /// Span where managed values of the array should be stored. + /// + /// + /// + public Span GetManagedValuesDestination(int length) + { + if (_allocatedMemory == IntPtr.Zero) + return null; + + _managedArray = new T*[length]; + return Unsafe.As(_managedArray); + } + + /// + /// Returns a span that points to the memory where the native values of the array are stored after the native call. + /// + /// Length of the array. + /// Span over the native values of the array. + /// + /// + /// + public ReadOnlySpan GetNativeValuesSource(int length) + { + if (_allocatedMemory == IntPtr.Zero) + return default; + + _span = new Span((void*)_allocatedMemory, length * _sizeOfNativeElement); + return _span; + } + + /// + /// Returns a span that points to the memory where the native values of the array should be stored. + /// + /// Span where native values of the array should be stored. + /// + /// + /// + public Span GetNativeValuesDestination() => _span; + + /// + /// Returns a reference to the marshalled array. + /// + public ref byte GetPinnableReference() => ref MemoryMarshal.GetReference(_span); + + /// + /// Returns the native value representing the array. + /// + /// + /// + /// + public byte* ToNativeValue() => (byte*)Unsafe.AsPointer(ref GetPinnableReference()); + + /// + /// Sets the native value representing the array. + /// + /// The native value. + /// + /// + /// + public void FromNativeValue(byte* value) => _allocatedMemory = (IntPtr)value; + + /// + /// Returns the managed array. + /// + /// + /// + /// + public T*[]? ToManaged() => _managedArray; + + /// + /// Frees native resources. + /// + /// + /// + /// + public void FreeNative() + { + Marshal.FreeCoTaskMem(_allocatedMemory); + } + } +} diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/MarshallingAttributeInfo.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/MarshallingAttributeInfo.cs index f53c7b82bdce9a..7165e9cfc3f814 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/MarshallingAttributeInfo.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/MarshallingAttributeInfo.cs @@ -798,11 +798,11 @@ private MarshallingInfo CreateArrayMarshallingInfo( INamedTypeSymbol? arrayMarshaller; if (elementType is IPointerTypeSymbol { PointedAtType: ITypeSymbol pointedAt }) { - arrayMarshaller = _compilation.GetTypeByMetadataName(TypeNames.System_Runtime_InteropServices_GeneratedMarshalling_PtrArrayMarshaller_Metadata)?.Construct(pointedAt); + arrayMarshaller = _compilation.GetTypeByMetadataName(TypeNames.System_Runtime_InteropServices_PointerArrayMarshaller_Metadata)?.Construct(pointedAt); } else { - arrayMarshaller = _compilation.GetTypeByMetadataName(TypeNames.System_Runtime_InteropServices_GeneratedMarshalling_ArrayMarshaller_Metadata)?.Construct(elementType); + arrayMarshaller = _compilation.GetTypeByMetadataName(TypeNames.System_Runtime_InteropServices_ArrayMarshaller_Metadata)?.Construct(elementType); } if (arrayMarshaller is null) diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/TypeNames.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/TypeNames.cs index 310299ed6d9f40..2e2f65c02c4f39 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/TypeNames.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/TypeNames.cs @@ -56,9 +56,9 @@ public static string MarshalEx(InteropGenerationOptions options) public const string System_Runtime_InteropServices_MemoryMarshal = "System.Runtime.InteropServices.MemoryMarshal"; - public const string System_Runtime_InteropServices_GeneratedMarshalling_ArrayMarshaller_Metadata = "System.Runtime.InteropServices.GeneratedMarshalling.ArrayMarshaller`1"; + public const string System_Runtime_InteropServices_ArrayMarshaller_Metadata = "System.Runtime.InteropServices.ArrayMarshaller`1"; - public const string System_Runtime_InteropServices_GeneratedMarshalling_PtrArrayMarshaller_Metadata = "System.Runtime.InteropServices.GeneratedMarshalling.PtrArrayMarshaller`1"; + public const string System_Runtime_InteropServices_PointerArrayMarshaller_Metadata = "System.Runtime.InteropServices.PointerArrayMarshaller`1"; public const string System_Runtime_InteropServices_SafeHandle = "System.Runtime.InteropServices.SafeHandle"; diff --git a/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs b/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs index 09ce851384de41..9a95bef3524a78 100644 --- a/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs +++ b/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs @@ -99,7 +99,7 @@ public sealed partial class AllowReversePInvokeCallsAttribute : System.Attribute public AllowReversePInvokeCallsAttribute() { } } [System.CLSCompliant(false)] - [System.Runtime.InteropServices.CustomTypeMarshaller(typeof(string), BufferSize = 0x100, + [System.Runtime.InteropServices.CustomTypeMarshallerAttribute(typeof(string), BufferSize = 0x100, Features = System.Runtime.InteropServices.CustomTypeMarshallerFeatures.UnmanagedResources | System.Runtime.InteropServices.CustomTypeMarshallerFeatures.CallerAllocatedBuffer | System.Runtime.InteropServices.CustomTypeMarshallerFeatures.TwoStageMarshalling )] @@ -112,6 +112,27 @@ public void FromNativeValue(byte* value) { } public string? ToManaged() { throw null; } public void FreeNative() { } } + [System.CLSCompliantAttribute(false)] + [System.Runtime.InteropServices.CustomTypeMarshallerAttribute(typeof(System.Runtime.InteropServices.CustomTypeMarshallerAttribute.GenericPlaceholder[]), + System.Runtime.InteropServices.CustomTypeMarshallerKind.LinearCollection, BufferSize = 0x200, + Features = System.Runtime.InteropServices.CustomTypeMarshallerFeatures.UnmanagedResources + | System.Runtime.InteropServices.CustomTypeMarshallerFeatures.CallerAllocatedBuffer + | System.Runtime.InteropServices.CustomTypeMarshallerFeatures.TwoStageMarshalling)] + public unsafe ref struct ArrayMarshaller + { + public ArrayMarshaller(int sizeOfNativeElement) { } + public ArrayMarshaller(T[]? array, int sizeOfNativeElement) { } + public ArrayMarshaller(T[]? array, System.Span buffer, int sizeOfNativeElement) { } + public System.ReadOnlySpan GetManagedValuesSource() { throw null; } + public System.Span GetManagedValuesDestination(int length) { throw null; } + public System.ReadOnlySpan GetNativeValuesSource(int length) { throw null; } + public System.Span GetNativeValuesDestination() { throw null; } + public ref byte GetPinnableReference() { throw null; } + public byte* ToNativeValue() { throw null; } + public void FromNativeValue(byte* value) { } + public T[]? ToManaged() { throw null; } + public void FreeNative() { } + } public readonly partial struct ArrayWithOffset : System.IEquatable { private readonly object _dummy; @@ -975,6 +996,27 @@ public sealed partial class OptionalAttribute : System.Attribute { public OptionalAttribute() { } } + [System.CLSCompliantAttribute(false)] + [System.Runtime.InteropServices.CustomTypeMarshallerAttribute(typeof(System.Runtime.InteropServices.CustomTypeMarshallerAttribute.GenericPlaceholder*[]), + System.Runtime.InteropServices.CustomTypeMarshallerKind.LinearCollection, BufferSize = 0x200, + Features = System.Runtime.InteropServices.CustomTypeMarshallerFeatures.UnmanagedResources + | System.Runtime.InteropServices.CustomTypeMarshallerFeatures.CallerAllocatedBuffer + | System.Runtime.InteropServices.CustomTypeMarshallerFeatures.TwoStageMarshalling)] + public unsafe ref struct PointerArrayMarshaller where T : unmanaged + { + public PointerArrayMarshaller(int sizeOfNativeElement) { } + public PointerArrayMarshaller(T*[]? array, int sizeOfNativeElement) { } + public PointerArrayMarshaller(T*[]? array, System.Span buffer, int sizeOfNativeElement) { } + public System.ReadOnlySpan GetManagedValuesSource() { throw null; } + public System.Span GetManagedValuesDestination(int length) { throw null; } + public System.ReadOnlySpan GetNativeValuesSource(int length) { throw null; } + public System.Span GetNativeValuesDestination() { throw null; } + public ref byte GetPinnableReference() { throw null; } + public byte* ToNativeValue() { throw null; } + public void FromNativeValue(byte* value) { } + public T*[]? ToManaged() { throw null; } + public void FreeNative() { } + } public enum PosixSignal { [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("windows")] @@ -1296,7 +1338,7 @@ public UnmanagedCallersOnlyAttribute() { } public string? EntryPoint; } [System.CLSCompliant(false)] - [System.Runtime.InteropServices.CustomTypeMarshaller(typeof(string), BufferSize = 0x100, + [System.Runtime.InteropServices.CustomTypeMarshallerAttribute(typeof(string), BufferSize = 0x100, Features = System.Runtime.InteropServices.CustomTypeMarshallerFeatures.UnmanagedResources | System.Runtime.InteropServices.CustomTypeMarshallerFeatures.CallerAllocatedBuffer | System.Runtime.InteropServices.CustomTypeMarshallerFeatures.TwoStageMarshalling )] @@ -1310,7 +1352,7 @@ public void FromNativeValue(byte* value) { } public void FreeNative() { } } [System.CLSCompliant(false)] - [System.Runtime.InteropServices.CustomTypeMarshaller(typeof(string), BufferSize = 0x100, + [System.Runtime.InteropServices.CustomTypeMarshallerAttribute(typeof(string), BufferSize = 0x100, Features = System.Runtime.InteropServices.CustomTypeMarshallerFeatures.UnmanagedResources | System.Runtime.InteropServices.CustomTypeMarshallerFeatures.CallerAllocatedBuffer | System.Runtime.InteropServices.CustomTypeMarshallerFeatures.TwoStageMarshalling )] diff --git a/src/libraries/System.Runtime.InteropServices/tests/Ancillary.Interop/Ancillary.Interop.csproj b/src/libraries/System.Runtime.InteropServices/tests/Ancillary.Interop/Ancillary.Interop.csproj index b8e9081def83a8..629c77c4b3493b 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/Ancillary.Interop/Ancillary.Interop.csproj +++ b/src/libraries/System.Runtime.InteropServices/tests/Ancillary.Interop/Ancillary.Interop.csproj @@ -10,7 +10,4 @@ $(DefineConstants);LIBRARYIMPORT_GENERATOR_TEST - - - From d0dd0d5637a46ce9ed3c95f5c90b0a5fd8422e66 Mon Sep 17 00:00:00 2001 From: Elinor Fung Date: Mon, 18 Apr 2022 14:12:30 -0700 Subject: [PATCH 2/2] Remove unnecessary code --- .../LibraryImportGenerator/PInvokeStubCodeGenerator.cs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/PInvokeStubCodeGenerator.cs b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/PInvokeStubCodeGenerator.cs index 7089b635941a80..d5f7fd9f7f10a5 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/PInvokeStubCodeGenerator.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/PInvokeStubCodeGenerator.cs @@ -198,15 +198,6 @@ BoundGenerator CreateGenerator(TypePositionInfo p) { try { - // TODO: Remove once helper types (like ArrayMarshaller) are part of the runtime - // This check is to help with enabling the source generator for runtime libraries without making each - // library directly reference System.Memory and System.Runtime.CompilerServices.Unsafe unless it needs to - if (p.MarshallingAttributeInfo is MissingSupportMarshallingInfo - && (environment.TargetFramework == TargetFramework.Net && environment.TargetFrameworkVersion.Major >= 7)) - { - throw new MarshallingNotSupportedException(p, this); - } - return new BoundGenerator(p, generatorFactory.Create(p, this)); } catch (MarshallingNotSupportedException e)