Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update /// comments for new InteropServices APIs #72473

Merged
merged 6 commits into from
Jul 20, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,49 @@

namespace System.Runtime.InteropServices
{
/// <summary>
/// Indicates the processor architecture.
/// </summary>
public enum Architecture
{
/// <summary>
/// An Intel-based 32-bit processor architecture.
/// </summary>
X86,
/// <summary>
/// An Intel-based 64-bit processor architecture.
/// </summary>
X64,
/// <summary>
/// A 32-bit ARM processor architecture.
/// </summary>
AaronRobinsonMSFT marked this conversation as resolved.
Show resolved Hide resolved
Arm,
/// <summary>
/// A 64-bit ARM processor architecture.
/// </summary>
Arm64,
/// <summary>
/// The WebAssembly platform.
/// </summary>
Wasm,
/// <summary>
/// A S390x platform architecture.
/// </summary>
S390x,
/// <summary>
/// A LoongArch64 processor architecture.
/// </summary>
LoongArch64,
/// <summary>
/// A 32-bit ARMv6 processor architecture.
/// </summary>
/// <remarks>
/// This value indicates ARMv6 base instructions, VFPv2 floating point support and registers, hard-float ABI, and no compact instruction set.
/// </remarks>
Armv6,
/// <summary>
/// A PowerPC 64-bit (little-endian) processor architecture.
/// </summary>
Ppc64le,
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ namespace System.Runtime.InteropServices.Marshalling
public static unsafe class ArrayMarshaller<T, TUnmanagedElement>
where TUnmanagedElement : unmanaged
{
/// <summary>
/// Allocates memory for the unmanaged representation of the array.
/// </summary>
/// <param name="managed">The managed array</param>
/// <param name="numElements">The unmanaged element count</param>
/// <returns>The unmanaged pointer to the allocated memory</returns>
public static TUnmanagedElement* AllocateContainerForUnmanagedElements(T[]? managed, out int numElements)
{
if (managed is null)
Expand All @@ -37,12 +43,29 @@ public static unsafe class ArrayMarshaller<T, TUnmanagedElement>
return (TUnmanagedElement*)Marshal.AllocCoTaskMem(spaceToAllocate);
}

/// <summary>
/// Gets a source for the managed elements in the array.
/// </summary>
/// <param name="managed">The managed array</param>
/// <returns>The <see cref="ReadOnlySpan{T}"/> containing the managed elements to marshal</returns>
public static ReadOnlySpan<T> GetManagedValuesSource(T[]? managed)
=> managed;

/// <summary>
/// Gets a destination for the unmanaged elements in the array.
/// </summary>
/// <param name="unmanaged">The unmanaged allocation</param>
/// <param name="numElements">The unmanaged element count</param>
/// <returns>The <see cref="Span{TUnmanagedElement}"/> of unmanaged elements</returns>
public static Span<TUnmanagedElement> GetUnmanagedValuesDestination(TUnmanagedElement* unmanaged, int numElements)
=> new Span<TUnmanagedElement>(unmanaged, numElements);

/// <summary>
/// Allocates memory for the managed representation of the array.
/// </summary>
/// <param name="unmanaged">The unmanaged array</param>
/// <param name="numElements">The unmanaged element count</param>
/// <returns>The managed array</returns>
public static T[]? AllocateContainerForManagedElements(TUnmanagedElement* unmanaged, int numElements)
{
if (unmanaged is null)
Expand All @@ -51,17 +74,41 @@ public static Span<TUnmanagedElement> GetUnmanagedValuesDestination(TUnmanagedEl
return new T[numElements];
}

/// <summary>
/// Gets a destination for the managed elements in the array.
/// </summary>
/// <param name="managed">The managed array</param>
/// <returns>The <see cref="Span{T}"/> of managed elements</returns>
public static Span<T> GetManagedValuesDestination(T[]? managed)
=> managed;

/// <summary>
/// Gets a source for the unmanaged elements in the array.
/// </summary>
/// <param name="unmanagedValue">The unmanaged array</param>
/// <param name="numElements">The unmanaged element count</param>
/// <returns>The <see cref="ReadOnlySpan{TUnmanagedElement}"/> containing the unmanaged elements to marshal</returns>
public static ReadOnlySpan<TUnmanagedElement> GetUnmanagedValuesSource(TUnmanagedElement* unmanagedValue, int numElements)
=> new ReadOnlySpan<TUnmanagedElement>(unmanagedValue, numElements);

/// <summary>
/// Frees memory for the unmanaged array
AaronRobinsonMSFT marked this conversation as resolved.
Show resolved Hide resolved
/// </summary>
/// <param name="unmanaged">Unmanaged array</param>
public static void Free(TUnmanagedElement* unmanaged)
=> Marshal.FreeCoTaskMem((IntPtr)unmanaged);

/// <summary>
/// Marshaller for marshalling a array from managed to unmanaged.
/// </summary>
public ref struct ManagedToUnmanagedIn
{
/// <summary>
/// Requested caller-allocated buffer size.
/// </summary>
/// <remarks>
/// Represents a potential optimization for the marshaller.
/// </remarks>
// We'll keep the buffer size at a maximum of 200 bytes to avoid overflowing the stack.
public static int BufferSize { get; } = 0x200 / sizeof(TUnmanagedElement);

Expand Down Expand Up @@ -134,6 +181,11 @@ public void Free()
NativeMemory.Free(_allocatedMemory);
}

/// <summary>
/// Gets a pinnable reference to the managed span to a pointer to pass directly to unmanaged code.
AaronRobinsonMSFT marked this conversation as resolved.
Show resolved Hide resolved
/// </summary>
/// <param name="array">The managed array.</param>
/// <returns>The reference that can be pinned and directly passed to unmanaged code.</returns>
public static ref T GetPinnableReference(T[]? array)
{
if (array is null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ public static unsafe class PointerArrayMarshaller<T, TUnmanagedElement>
where T : unmanaged
where TUnmanagedElement : unmanaged
{
/// <summary>
/// Allocates memory for the unmanaged representation of the array.
/// </summary>
/// <param name="managed">The managed array to marshal</param>
/// <param name="numElements">The unmanaged element count</param>
/// <returns>The unmanaged pointer to the allocated memory</returns>
public static TUnmanagedElement* AllocateContainerForUnmanagedElements(T*[]? managed, out int numElements)
{
if (managed is null)
Expand All @@ -38,12 +44,29 @@ public static unsafe class PointerArrayMarshaller<T, TUnmanagedElement>
return (TUnmanagedElement*)Marshal.AllocCoTaskMem(spaceToAllocate);
}

/// <summary>
/// Gets a source for the managed elements in the array.
/// </summary>
/// <param name="managed">The managed array</param>
/// <returns>The <see cref="ReadOnlySpan{IntPtr}"/> containing the managed elements to marshal</returns>
public static ReadOnlySpan<IntPtr> GetManagedValuesSource(T*[]? managed)
=> Unsafe.As<IntPtr[]>(managed);

/// <summary>
/// Gets a destination for the unmanaged elements in the array.
/// </summary>
/// <param name="unmanaged">The unmanaged allocation</param>
/// <param name="numElements">The unmanaged element count</param>
/// <returns>The <see cref="Span{TUnmanagedElement}"/> of unmanaged elements</returns>
public static Span<TUnmanagedElement> GetUnmanagedValuesDestination(TUnmanagedElement* unmanaged, int numElements)
=> new Span<TUnmanagedElement>(unmanaged, numElements);

/// <summary>
/// Allocates memory for the managed representation of the array.
/// </summary>
/// <param name="unmanaged">The unmanaged array</param>
/// <param name="numElements">The unmanaged element count</param>
/// <returns>The managed array</returns>
public static T*[]? AllocateContainerForManagedElements(TUnmanagedElement* unmanaged, int numElements)
{
if (unmanaged is null)
Expand All @@ -52,17 +75,42 @@ public static Span<TUnmanagedElement> GetUnmanagedValuesDestination(TUnmanagedEl
return new T*[numElements];
}

/// <summary>
/// Gets a destination for the managed elements in the array.
/// </summary>
/// <param name="managed">The managed array</param>
/// <returns>The <see cref="Span{T}"/> of managed elements</returns>
public static Span<IntPtr> GetManagedValuesDestination(T*[]? managed)
=> Unsafe.As<IntPtr[]>(managed);

/// <summary>
/// Gets a source for the unmanaged elements in the array.
/// </summary>
/// <param name="unmanagedValue">The unmanaged array</param>
/// <param name="numElements">The unmanaged element count</param>
/// <returns>The <see cref="ReadOnlySpan{TUnmanagedElement}"/> containing the unmanaged elements to marshal</returns>
public static ReadOnlySpan<TUnmanagedElement> GetUnmanagedValuesSource(TUnmanagedElement* unmanagedValue, int numElements)
=> new ReadOnlySpan<TUnmanagedElement>(unmanagedValue, numElements);

/// <summary>
/// Frees memory for the unmanaged array
AaronRobinsonMSFT marked this conversation as resolved.
Show resolved Hide resolved
/// </summary>
/// <param name="unmanaged">Unmanaged array</param>
public static void Free(TUnmanagedElement* unmanaged)
=> Marshal.FreeCoTaskMem((IntPtr)unmanaged);

/// <summary>
/// Marshaller for marshalling a array from managed to unmanaged.
/// </summary>
public ref struct ManagedToUnmanagedIn
{
/// <summary>
/// Requested caller-allocated buffer size.
/// </summary>
/// <remarks>
/// Represents a potential optimization for the marshaller.
/// </remarks>
// We'll keep the buffer size at a maximum of 200 bytes to avoid overflowing the stack.
public static int BufferSize => 0x200 / sizeof(TUnmanagedElement);

private T*[]? _managedArray;
Expand Down Expand Up @@ -134,6 +182,11 @@ public void Free()
NativeMemory.Free(_allocatedMemory);
}

/// <summary>
/// Gets a pinnable reference to the managed span to a pointer to pass directly to unmanaged code.
AaronRobinsonMSFT marked this conversation as resolved.
Show resolved Hide resolved
/// </summary>
/// <param name="array">The managed array.</param>
/// <returns>The reference that can be pinned and directly passed to unmanaged code.</returns>
public static ref byte GetPinnableReference(T*[]? array)
{
if (array is null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,11 @@ public void Free()
NativeMemory.Free(_allocatedMemory);
}

/// <summary>
/// Pin the managed span to a pointer to pass directly to unmanaged code.
AaronRobinsonMSFT marked this conversation as resolved.
Show resolved Hide resolved
AaronRobinsonMSFT marked this conversation as resolved.
Show resolved Hide resolved
/// </summary>
/// <param name="managed">The managed span.</param>
/// <returns>A reference that can be pinned and directly passed to unmanaged code.</returns>
public static ref T GetPinnableReference(Span<T> managed)
{
return ref MemoryMarshal.GetReference(managed);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,17 @@ namespace System.Runtime.InteropServices
#endif
enum StringMarshalling
{
/// <summary>
/// Indicates the user is suppling a specific marshaller in <see cref="LibraryImportAttribute.StringMarshallingCustomType"/>.
/// </summary>
Custom = 0,
Utf8, // UTF-8
Utf16, // UTF-16, machine-endian
/// <summary>
/// Use the platform-provided UTF-8 marshaller.
/// </summary>
Utf8,
/// <summary>
/// Use the platform-provided UTF-16 marshaller.
/// </summary>
Utf16,
}
}