Skip to content

Commit

Permalink
Update /// comments for new InteropServices APIs (#72473)
Browse files Browse the repository at this point in the history
* Update /// for official documentation.

Co-authored-by: Stephen Toub <stoub@microsoft.com>
Co-authored-by: Elinor Fung <elfung@microsoft.com>
Co-authored-by: Jeremy Koritzinsky <jkoritzinsky@gmail.com>
  • Loading branch information
4 people committed Jul 20, 2022
1 parent 58efb7e commit a90439b
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,52 @@

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>
/// <remarks>
/// This value indicates ARMv7 base instructions, VFPv3 floating point support and registers, and Thumb2 compact instruction set.
/// </remarks>
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.
/// </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 array.
/// </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.
/// </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 array.
/// </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>
/// Gets a pinnable reference to the managed span.
/// </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,
}
}

0 comments on commit a90439b

Please sign in to comment.