diff options
10 files changed, 391 insertions, 197 deletions
diff --git a/eng/generators.targets b/eng/generators.targets index 5d806b69a18..f830dbd52f2 100644 --- a/eng/generators.targets +++ b/eng/generators.targets @@ -50,16 +50,6 @@ Include="$(CoreLibSharedDir)System\Runtime\InteropServices\LibraryImportAttribute.cs" /> <Compile Condition="'$(NetCoreAppCurrentTargetFrameworkMoniker)' != '$(TargetFrameworkMoniker)'" Include="$(CoreLibSharedDir)System\Runtime\InteropServices\StringMarshalling.cs" /> - - <!-- Only add the following files if we are on the latest TFM (that is, net7) and the project is SPCL or has references to System.Runtime.CompilerServices.Unsafe and System.Memory --> - <Compile Condition="'$(NetCoreAppCurrentTargetFrameworkMoniker)' == '$(TargetFrameworkMoniker)' - and ( - '$(MSBuildProjectName)' == 'System.Private.CoreLib' - or '$(EnableLibraryImportGenerator)' == 'true' - or ('@(Reference)' != '' - and @(Reference->AnyHaveMetadataValue('Identity', 'System.Memory'))) - or ('@(ProjectReference)' != '' - and @(ProjectReference->AnyHaveMetadataValue('Identity', '$(CoreLibProject)'))))" Include="$(LibrariesProjectRoot)Common\src\System\Runtime\InteropServices\ArrayMarshaller.cs" /> </ItemGroup> <ItemGroup> 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 f5c5277a7d3..00000000000 --- 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<T> - { - 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<byte>.Empty, sizeOfNativeElement) - { - } - - public ArrayMarshaller(T[]? managed, Span<byte> 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<byte>((void*)_allocatedMemory, spaceToAllocate); - } - } - - public ReadOnlySpan<T> GetManagedValuesSource() => _managedArray; - public Span<T> GetManagedValuesDestination(int length) => _allocatedMemory == IntPtr.Zero ? null : _managedArray = new T[length]; - public Span<byte> GetNativeValuesDestination() => NativeValueStorage; - - public ReadOnlySpan<byte> GetNativeValuesSource(int length) - { - return _allocatedMemory == IntPtr.Zero ? default : NativeValueStorage = new Span<byte>((void*)_allocatedMemory, length * _sizeOfNativeElement); - } - private Span<byte> 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<T> 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<byte>.Empty, sizeOfNativeElement) - { - } - - public PtrArrayMarshaller(T*[]? managed, Span<byte> 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<byte>((void*)_allocatedMemory, spaceToAllocate); - } - } - - public ReadOnlySpan<IntPtr> GetManagedValuesSource() => Unsafe.As<IntPtr[]>(_managedArray); - public Span<IntPtr> GetManagedValuesDestination(int length) => _allocatedMemory == IntPtr.Zero ? null : Unsafe.As<IntPtr[]>(_managedArray = new T*[length]); - public Span<byte> GetNativeValuesDestination() => NativeValueStorage; - - public ReadOnlySpan<byte> GetNativeValuesSource(int length) - { - return _allocatedMemory == IntPtr.Zero ? default : NativeValueStorage = new Span<byte>((void*)_allocatedMemory, length * _sizeOfNativeElement); - } - private Span<byte> 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 b76fee8bac7..985fcd2e870 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 @@ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\AllowReversePInvokeCallsAttribute.cs" /> <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\AnsiStringMarshaller.cs" /> <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\Architecture.cs" /> + <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\ArrayMarshaller.cs" /> <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\ArrayWithOffset.cs" /> <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\BestFitMappingAttribute.cs" /> <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\BStrWrapper.cs" /> @@ -872,6 +873,7 @@ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\OptionalAttribute.cs" /> <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\OSPlatform.cs" /> <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\OutAttribute.cs" /> + <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\PointerArrayMarshaller.cs" /> <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\PosixSignal.cs" /> <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\PosixSignalContext.cs" /> <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\PosixSignalRegistration.cs" /> 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 00000000000..4282b96f630 --- /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 +{ + /// <summary> + /// Marshaller for arrays + /// </summary> + /// <typeparam name="T">Array element type</typeparam> + [CLSCompliant(false)] + [CustomTypeMarshaller(typeof(CustomTypeMarshallerAttribute.GenericPlaceholder[]), + CustomTypeMarshallerKind.LinearCollection, BufferSize = 0x200, + Features = CustomTypeMarshallerFeatures.UnmanagedResources | CustomTypeMarshallerFeatures.CallerAllocatedBuffer | CustomTypeMarshallerFeatures.TwoStageMarshalling)] + public unsafe ref struct ArrayMarshaller<T> + { + private readonly int _sizeOfNativeElement; + + private T[]? _managedArray; + private IntPtr _allocatedMemory; + private Span<byte> _span; + + /// <summary> + /// Initializes a new instance of the <see cref="ArrayMarshaller{T}"/>. + /// </summary> + /// <param name="sizeOfNativeElement">Size of the native element in bytes.</param> + public ArrayMarshaller(int sizeOfNativeElement) + : this() + { + _sizeOfNativeElement = sizeOfNativeElement; + } + + /// <summary> + /// Initializes a new instance of the <see cref="ArrayMarshaller{T}"/>. + /// </summary> + /// <param name="array">Array to be marshalled.</param> + /// <param name="sizeOfNativeElement">Size of the native element in bytes.</param> + public ArrayMarshaller(T[]? array, int sizeOfNativeElement) + : this(array, Span<byte>.Empty, sizeOfNativeElement) + { } + + /// <summary> + /// Initializes a new instance of the <see cref="ArrayMarshaller{T}"/>. + /// </summary> + /// <param name="array">Array to be marshalled.</param> + /// <param name="buffer">Buffer that may be used for marshalling.</param> + /// <param name="sizeOfNativeElement">Size of the native element in bytes.</param> + /// <remarks> + /// The <paramref name="buffer"/> must not be movable - that is, it should not be + /// on the managed heap or it should be pinned. + /// <seealso cref="CustomTypeMarshallerFeatures.CallerAllocatedBuffer"/> + /// </remarks> + public ArrayMarshaller(T[]? array, Span<byte> 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<byte>((void*)_allocatedMemory, spaceToAllocate); + } + } + + /// <summary> + /// Gets a span that points to the memory where the managed values of the array are stored. + /// </summary> + /// <returns>Span over managed values of the array.</returns> + /// <remarks> + /// <seealso cref="CustomTypeMarshallerDirection.In"/> + /// </remarks> + public ReadOnlySpan<T> GetManagedValuesSource() => _managedArray; + + /// <summary> + /// Gets a span that points to the memory where the unmarshalled managed values of the array should be stored. + /// </summary> + /// <param name="length">Length of the array.</param> + /// <returns>Span where managed values of the array should be stored.</returns> + /// <remarks> + /// <seealso cref="CustomTypeMarshallerDirection.Out"/> + /// </remarks> + public Span<T> GetManagedValuesDestination(int length) => _allocatedMemory == IntPtr.Zero ? null : _managedArray = new T[length]; + + /// <summary> + /// Returns a span that points to the memory where the native values of the array are stored after the native call. + /// </summary> + /// <param name="length">Length of the array.</param> + /// <returns>Span over the native values of the array.</returns> + /// <remarks> + /// <seealso cref="CustomTypeMarshallerDirection.Out"/> + /// </remarks> + public ReadOnlySpan<byte> GetNativeValuesSource(int length) + { + return _allocatedMemory == IntPtr.Zero ? default : _span = new Span<byte>((void*)_allocatedMemory, length * _sizeOfNativeElement); + } + + /// <summary> + /// Returns a span that points to the memory where the native values of the array should be stored. + /// </summary> + /// <returns>Span where native values of the array should be stored.</returns> + /// <remarks> + /// <seealso cref="CustomTypeMarshallerDirection.In"/> + /// </remarks> + public Span<byte> GetNativeValuesDestination() => _span; + + /// <summary> + /// Returns a reference to the marshalled array. + /// </summary> + public ref byte GetPinnableReference() => ref MemoryMarshal.GetReference(_span); + + /// <summary> + /// Returns the native value representing the array. + /// </summary> + /// <remarks> + /// <seealso cref="CustomTypeMarshallerFeatures.TwoStageMarshalling"/> + /// </remarks> + public byte* ToNativeValue() => (byte*)Unsafe.AsPointer(ref GetPinnableReference()); + + /// <summary> + /// Sets the native value representing the array. + /// </summary> + /// <param name="value">The native value.</param> + /// <remarks> + /// <seealso cref="CustomTypeMarshallerFeatures.TwoStageMarshalling"/> + /// </remarks> + public void FromNativeValue(byte* value) + { + _allocatedMemory = (IntPtr)value; + } + + /// <summary> + /// Returns the managed array. + /// </summary> + /// <remarks> + /// <seealso cref="CustomTypeMarshallerDirection.Out"/> + /// </remarks> + public T[]? ToManaged() => _managedArray; + + /// <summary> + /// Frees native resources. + /// </summary> + /// <remarks> + /// <seealso cref="CustomTypeMarshallerFeatures.UnmanagedResources"/> + /// </remarks> + 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 00000000000..0d998b834a1 --- /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 +{ + /// <summary> + /// Marshaller for arrays of pointers + /// </summary> + /// <typeparam name="T">Array element pointer type</typeparam> + [CLSCompliant(false)] + [CustomTypeMarshaller(typeof(CustomTypeMarshallerAttribute.GenericPlaceholder*[]), + CustomTypeMarshallerKind.LinearCollection, BufferSize = 0x200, + Features = CustomTypeMarshallerFeatures.UnmanagedResources | CustomTypeMarshallerFeatures.CallerAllocatedBuffer | CustomTypeMarshallerFeatures.TwoStageMarshalling)] + public unsafe ref struct PointerArrayMarshaller<T> where T : unmanaged + { + private readonly int _sizeOfNativeElement; + + private T*[]? _managedArray; + private IntPtr _allocatedMemory; + private Span<byte> _span; + + /// <summary> + /// Initializes a new instance of the <see cref="PointerArrayMarshaller{T}"/>. + /// </summary> + /// <param name="sizeOfNativeElement">Size of the native element in bytes.</param> + public PointerArrayMarshaller(int sizeOfNativeElement) + : this() + { + _sizeOfNativeElement = sizeOfNativeElement; + } + + /// <summary> + /// Initializes a new instance of the <see cref="PointerArrayMarshaller{T}"/>. + /// </summary> + /// <param name="array">Array to be marshalled.</param> + /// <param name="sizeOfNativeElement">Size of the native element in bytes.</param> + public PointerArrayMarshaller(T*[]? array, int sizeOfNativeElement) + : this(array, Span<byte>.Empty, sizeOfNativeElement) + { } + + /// <summary> + /// Initializes a new instance of the <see cref="PointerArrayMarshaller{T}"/>. + /// </summary> + /// <param name="array">Array to be marshalled.</param> + /// <param name="buffer">Buffer that may be used for marshalling.</param> + /// <param name="sizeOfNativeElement">Size of the native element in bytes.</param> + /// <remarks> + /// The <paramref name="buffer"/> must not be movable - that is, it should not be + /// on the managed heap or it should be pinned. + /// <seealso cref="CustomTypeMarshallerFeatures.CallerAllocatedBuffer"/> + /// </remarks> + public PointerArrayMarshaller(T*[]? array, Span<byte> 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<byte>((void*)_allocatedMemory, spaceToAllocate); + } + } + + /// <summary> + /// Gets a span that points to the memory where the managed values of the array are stored. + /// </summary> + /// <returns>Span over managed values of the array.</returns> + /// <remarks> + /// <seealso cref="CustomTypeMarshallerDirection.In"/> + /// </remarks> + public ReadOnlySpan<IntPtr> GetManagedValuesSource() => Unsafe.As<IntPtr[]>(_managedArray); + + /// <summary> + /// Gets a span that points to the memory where the unmarshalled managed values of the array should be stored. + /// </summary> + /// <param name="length">Length of the array.</param> + /// <returns>Span where managed values of the array should be stored.</returns> + /// <remarks> + /// <seealso cref="CustomTypeMarshallerDirection.Out"/> + /// </remarks> + public Span<IntPtr> GetManagedValuesDestination(int length) + { + if (_allocatedMemory == IntPtr.Zero) + return null; + + _managedArray = new T*[length]; + return Unsafe.As<IntPtr[]>(_managedArray); + } + + /// <summary> + /// Returns a span that points to the memory where the native values of the array are stored after the native call. + /// </summary> + /// <param name="length">Length of the array.</param> + /// <returns>Span over the native values of the array.</returns> + /// <remarks> + /// <seealso cref="CustomTypeMarshallerDirection.Out"/> + /// </remarks> + public ReadOnlySpan<byte> GetNativeValuesSource(int length) + { + if (_allocatedMemory == IntPtr.Zero) + return default; + + _span = new Span<byte>((void*)_allocatedMemory, length * _sizeOfNativeElement); + return _span; + } + + /// <summary> + /// Returns a span that points to the memory where the native values of the array should be stored. + /// </summary> + /// <returns>Span where native values of the array should be stored.</returns> + /// <remarks> + /// <seealso cref="CustomTypeMarshallerDirection.In"/> + /// </remarks> + public Span<byte> GetNativeValuesDestination() => _span; + + /// <summary> + /// Returns a reference to the marshalled array. + /// </summary> + public ref byte GetPinnableReference() => ref MemoryMarshal.GetReference(_span); + + /// <summary> + /// Returns the native value representing the array. + /// </summary> + /// <remarks> + /// <seealso cref="CustomTypeMarshallerFeatures.TwoStageMarshalling"/> + /// </remarks> + public byte* ToNativeValue() => (byte*)Unsafe.AsPointer(ref GetPinnableReference()); + + /// <summary> + /// Sets the native value representing the array. + /// </summary> + /// <param name="value">The native value.</param> + /// <remarks> + /// <seealso cref="CustomTypeMarshallerFeatures.TwoStageMarshalling"/> + /// </remarks> + public void FromNativeValue(byte* value) => _allocatedMemory = (IntPtr)value; + + /// <summary> + /// Returns the managed array. + /// </summary> + /// <remarks> + /// <seealso cref="CustomTypeMarshallerDirection.Out"/> + /// </remarks> + public T*[]? ToManaged() => _managedArray; + + /// <summary> + /// Frees native resources. + /// </summary> + /// <remarks> + /// <seealso cref="CustomTypeMarshallerFeatures.UnmanagedResources"/> + /// </remarks> + public void FreeNative() + { + Marshal.FreeCoTaskMem(_allocatedMemory); + } + } +} diff --git a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/PInvokeStubCodeGenerator.cs b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/PInvokeStubCodeGenerator.cs index 7089b635941..d5f7fd9f7f1 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 @@ namespace Microsoft.Interop { 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) 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 f53c7b82bdc..7165e9cfc3f 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 @@ namespace Microsoft.Interop 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 310299ed6d9..2e2f65c02c4 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 @@ namespace Microsoft.Interop 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 8a2fce98a39..53654b727d5 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 @@ namespace System.Runtime.InteropServices 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 @@ namespace System.Runtime.InteropServices 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<T> + { + public ArrayMarshaller(int sizeOfNativeElement) { } + public ArrayMarshaller(T[]? array, int sizeOfNativeElement) { } + public ArrayMarshaller(T[]? array, System.Span<byte> buffer, int sizeOfNativeElement) { } + public System.ReadOnlySpan<T> GetManagedValuesSource() { throw null; } + public System.Span<T> GetManagedValuesDestination(int length) { throw null; } + public System.ReadOnlySpan<byte> GetNativeValuesSource(int length) { throw null; } + public System.Span<byte> 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<System.Runtime.InteropServices.ArrayWithOffset> { private readonly object _dummy; @@ -1054,6 +1075,27 @@ namespace System.Runtime.InteropServices { 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<T> where T : unmanaged + { + public PointerArrayMarshaller(int sizeOfNativeElement) { } + public PointerArrayMarshaller(T*[]? array, int sizeOfNativeElement) { } + public PointerArrayMarshaller(T*[]? array, System.Span<byte> buffer, int sizeOfNativeElement) { } + public System.ReadOnlySpan<IntPtr> GetManagedValuesSource() { throw null; } + public System.Span<IntPtr> GetManagedValuesDestination(int length) { throw null; } + public System.ReadOnlySpan<byte> GetNativeValuesSource(int length) { throw null; } + public System.Span<byte> 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")] @@ -1375,7 +1417,7 @@ namespace System.Runtime.InteropServices 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 )] @@ -1389,7 +1431,7 @@ namespace System.Runtime.InteropServices 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 b8e9081def8..629c77c4b34 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>$(DefineConstants);LIBRARYIMPORT_GENERATOR_TEST</DefineConstants> </PropertyGroup> - <ItemGroup> - <Compile Include="$(LibrariesProjectRoot)Common/src/System/Runtime/InteropServices/ArrayMarshaller.cs" Link="ArrayMarshaller.cs" /> - </ItemGroup> </Project> |