diff --git a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.SzArray.cs b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.SzArray.cs
index c47349485..c2b009cea 100644
--- a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.SzArray.cs
+++ b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.SzArray.cs
@@ -8,6 +8,7 @@
using AsmResolver.PE.DotNet.Cil;
using AsmResolver.PE.DotNet.Metadata.Tables;
using WindowsRuntime.InteropGenerator.Factories;
+using WindowsRuntime.InteropGenerator.Generation;
using WindowsRuntime.InteropGenerator.References;
using static AsmResolver.PE.DotNet.Cil.CilOpCodes;
@@ -26,121 +27,129 @@ public static class SzArray
///
/// The for the SZ array type.
/// The instance to use.
+ /// The emit state for this invocation.
/// The module that will contain the type being created.
/// The resulting marshaller type.
public static void Marshaller(
SzArrayTypeSignature arrayType,
InteropReferences interopReferences,
+ InteropGeneratorEmitState emitState,
ModuleDefinition module,
out TypeDefinition marshallerType)
{
TypeSignature elementType = arrayType.BaseType;
- TypeSignature elementAbiType = elementType.GetAbiType(interopReferences);
- // We're declaring an 'internal static class' type
- marshallerType = new(
- ns: InteropUtf8NameFactory.TypeNamespace(arrayType),
- name: InteropUtf8NameFactory.TypeName(arrayType, "Marshaller"),
- attributes: TypeAttributes.AutoLayout | TypeAttributes.Sealed | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit,
- baseType: module.CorLibTypeFactory.Object.ToTypeDefOrRef());
-
- module.TopLevelTypes.Add(marshallerType);
-
- // Define the 'ConvertToUnmanaged' method as follows:
- //
- // public static void ConvertToUnmanaged(ReadOnlySpan<>, out uint size, out * array)
- MethodDefinition convertToUnmanagedMethod = new(
- name: "ConvertToUnmanaged"u8,
- attributes: MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig,
- signature: MethodSignature.CreateStatic(
- returnType: module.CorLibTypeFactory.Void,
- parameterTypes: [
- interopReferences.ReadOnlySpan1.MakeGenericValueType(elementType).Import(module),
- module.CorLibTypeFactory.UInt32.MakeByReferenceType(),
- elementAbiType.Import(module).MakePointerType().MakeByReferenceType()]))
+ // Emit the right marshaller based on the element type. We special case all different
+ // kinds of element types because some need specialized marshallers, and some need
+ // a generated element marshaller type. The marshaller itself just forwards all calls.
+ if (elementType.IsBlittable(interopReferences))
{
- CilOutParameterIndices = [2, 3],
- CilInstructions =
- {
- { Ldnull },
- { Throw } // TODO
- }
- };
-
- marshallerType.Methods.Add(convertToUnmanagedMethod);
-
- // Define the 'ConvertToManaged' method as follows:
- //
- // public static [] ConvertToManaged(uint size, * value)
- MethodDefinition convertToManagedMethod = new(
- name: "ConvertToManaged"u8,
- attributes: MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig,
- signature: MethodSignature.CreateStatic(
- returnType: arrayType.Import(module),
- parameterTypes: [
- module.CorLibTypeFactory.UInt32,
- elementAbiType.Import(module).MakePointerType()]))
+ marshallerType = InteropTypeDefinitionFactory.SzArrayMarshaller.BlittableValueType(
+ arrayType: arrayType,
+ interopReferences: interopReferences,
+ module: module);
+
+ module.TopLevelTypes.Add(marshallerType);
+ }
+ else if (elementType.IsConstructedKeyValuePairType(interopReferences))
{
- CilInstructions =
- {
- { Ldnull },
- { Throw } // TODO
- }
- };
-
- marshallerType.Methods.Add(convertToManagedMethod);
-
- // Define the 'CopyToManaged' method as follows:
- //
- // public static void CopyToManaged(uint size, * value, Span<> destination)
- MethodDefinition copyToManagedMethod = new(
- name: "CopyToManaged"u8,
- attributes: MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig,
- signature: MethodSignature.CreateStatic(
- returnType: module.CorLibTypeFactory.Void,
- parameterTypes: [
- module.CorLibTypeFactory.UInt32,
- elementAbiType.Import(module).MakePointerType(),
- interopReferences.Span1.MakeGenericValueType(elementType).Import(module)]))
+ TypeDefinition elementMarshallerType = InteropTypeDefinitionFactory.SzArrayElementMarshaller.KeyValuePair(
+ arrayType: arrayType,
+ interopReferences: interopReferences,
+ emitState: emitState,
+ module: module);
+
+ module.TopLevelTypes.Add(elementMarshallerType);
+
+ marshallerType = InteropTypeDefinitionFactory.SzArrayMarshaller.KeyValuePair(
+ arrayType: arrayType,
+ elementMarshallerType: elementMarshallerType,
+ interopReferences: interopReferences,
+ module: module);
+
+ module.TopLevelTypes.Add(marshallerType);
+ }
+ else if (elementType.IsManagedValueType(interopReferences))
{
- CilInstructions =
- {
- { Ldnull },
- { Throw } // TODO
- }
- };
-
- marshallerType.Methods.Add(copyToManagedMethod);
-
- // Define the 'CopyToUnmanaged' method as follows:
- //
- // public static void CopyToUnmanaged(ReadOnlySpan<> value, uint size, * destination)
- MethodDefinition copyToUnmanagedMethod = new(
- name: "CopyToUnmanaged"u8,
- attributes: MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig,
- signature: MethodSignature.CreateStatic(
- returnType: module.CorLibTypeFactory.Void,
- parameterTypes: [
- interopReferences.ReadOnlySpan1.MakeGenericValueType(elementType).Import(module),
- module.CorLibTypeFactory.UInt32,
- elementAbiType.Import(module).MakePointerType()]))
+ TypeDefinition elementMarshallerType = InteropTypeDefinitionFactory.SzArrayElementMarshaller.ManagedValueType(
+ arrayType: arrayType,
+ interopReferences: interopReferences,
+ emitState: emitState,
+ module: module);
+
+ module.TopLevelTypes.Add(elementMarshallerType);
+
+ marshallerType = InteropTypeDefinitionFactory.SzArrayMarshaller.ManagedValueType(
+ arrayType: arrayType,
+ elementMarshallerType: elementMarshallerType,
+ interopReferences: interopReferences,
+ module: module);
+
+ module.TopLevelTypes.Add(marshallerType);
+ }
+ else if (elementType.IsValueType)
{
- CilInstructions =
- {
- { Ldnull },
- { Throw } // TODO
- }
- };
-
- marshallerType.Methods.Add(copyToUnmanagedMethod);
-
- // Define the 'Free' method
- MethodDefinition freeMethod = InteropMethodDefinitionFactory.SzArrayMarshaller.Free(
- arrayType,
- interopReferences,
- module);
-
- marshallerType.Methods.Add(freeMethod);
+ TypeDefinition elementMarshallerType = InteropTypeDefinitionFactory.SzArrayElementMarshaller.UnmanagedValueType(
+ arrayType: arrayType,
+ interopReferences: interopReferences,
+ emitState: emitState,
+ module: module);
+
+ module.TopLevelTypes.Add(elementMarshallerType);
+
+ marshallerType = InteropTypeDefinitionFactory.SzArrayMarshaller.UnmanagedValueType(
+ arrayType: arrayType,
+ elementMarshallerType: elementMarshallerType,
+ interopReferences: interopReferences,
+ module: module);
+
+ module.TopLevelTypes.Add(marshallerType);
+ }
+ else if (elementType.IsTypeOfString())
+ {
+ marshallerType = InteropTypeDefinitionFactory.SzArrayMarshaller.String(
+ arrayType: arrayType,
+ interopReferences: interopReferences,
+ module: module);
+
+ module.TopLevelTypes.Add(marshallerType);
+ }
+ else if (elementType.IsTypeOfType(interopReferences))
+ {
+ marshallerType = InteropTypeDefinitionFactory.SzArrayMarshaller.Type(
+ arrayType: arrayType,
+ interopReferences: interopReferences,
+ module: module);
+
+ module.TopLevelTypes.Add(marshallerType);
+ }
+ else if (elementType.IsTypeOfException(interopReferences))
+ {
+ marshallerType = InteropTypeDefinitionFactory.SzArrayMarshaller.Exception(
+ arrayType: arrayType,
+ interopReferences: interopReferences,
+ module: module);
+
+ module.TopLevelTypes.Add(marshallerType);
+ }
+ else
+ {
+ TypeDefinition elementMarshallerType = InteropTypeDefinitionFactory.SzArrayElementMarshaller.ReferenceType(
+ arrayType: arrayType,
+ interopReferences: interopReferences,
+ emitState: emitState,
+ module: module);
+
+ module.TopLevelTypes.Add(elementMarshallerType);
+
+ marshallerType = InteropTypeDefinitionFactory.SzArrayMarshaller.ReferenceType(
+ arrayType: arrayType,
+ elementMarshallerType: elementMarshallerType,
+ interopReferences: interopReferences,
+ module: module);
+
+ module.TopLevelTypes.Add(marshallerType);
+ }
}
///
diff --git a/src/WinRT.Interop.Generator/Errors/WellKnownInteropExceptions.cs b/src/WinRT.Interop.Generator/Errors/WellKnownInteropExceptions.cs
index b7a32c0d8..d3f52d08d 100644
--- a/src/WinRT.Interop.Generator/Errors/WellKnownInteropExceptions.cs
+++ b/src/WinRT.Interop.Generator/Errors/WellKnownInteropExceptions.cs
@@ -597,6 +597,14 @@ public static WellKnownInteropException MethodRewriteSourceParameterTypeMismatch
return Exception(69, $"Parameter variable of type '{parameterType}' cannot be used to marshal a value of type '{returnType}' in generated interop method '{method}'.");
}
+ ///
+ /// A type doesn't have the Dispose method available.
+ ///
+ public static WellKnownInteropException MethodRewriteDisposeNotAvailableError(TypeSignature parameterType, MethodDefinition method)
+ {
+ return Exception(70, $"Value of type '{parameterType}' in generated interop method '{method}' cannot be disposed, as it is an unmanaged (or blittable) value type.");
+ }
+
///
/// Creates a new exception with the specified id and message.
///
diff --git a/src/WinRT.Interop.Generator/Extensions/WindowsRuntimeExtensions.cs b/src/WinRT.Interop.Generator/Extensions/WindowsRuntimeExtensions.cs
index 3a7805e0e..a9b14fe0e 100644
--- a/src/WinRT.Interop.Generator/Extensions/WindowsRuntimeExtensions.cs
+++ b/src/WinRT.Interop.Generator/Extensions/WindowsRuntimeExtensions.cs
@@ -583,6 +583,22 @@ public TypeSignature GetAbiType(InteropReferences interopReferences)
// For all other cases (e.g. interfaces, classes, delegates, etc.), the ABI type is always a pointer
return interopReferences.CorLibTypeFactory.Void.MakePointerType();
}
+
+ ///
+ /// Gets the raw ABI type for a given type (without unwrapping).
+ ///
+ /// The instance to use.
+ /// The raw ABI type for the input type.
+ public TypeSignature GetRawAbiType(InteropReferences interopReferences)
+ {
+ TypeSignature abiType = type.GetAbiType(interopReferences);
+
+ // If the ABI type is 'void*', the marshaller types return it as 'WindowsRuntimeObjectReferenceValue'.
+ // This allows callers to do proper lifetime management. For all other cases, the ABI type is the same.
+ return abiType.IsTypeOfVoidPointer()
+ ? interopReferences.WindowsRuntimeObjectReferenceValue.ToValueTypeSignature()
+ : abiType;
+ }
}
extension(TypeDefinition type)
diff --git a/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.IEnumerator1Impl.cs b/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.IEnumerator1Impl.cs
index c1ddf2a59..b2234b61c 100644
--- a/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.IEnumerator1Impl.cs
+++ b/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.IEnumerator1Impl.cs
@@ -15,10 +15,8 @@
namespace WindowsRuntime.InteropGenerator.Factories;
-///
-/// A factory for interop method definitions.
-///
-internal static partial class InteropMethodDefinitionFactory
+///
+internal partial class InteropMethodDefinitionFactory
{
///
/// Helpers for impl types for interfaces.
diff --git a/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.IList1Impl.cs b/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.IList1Impl.cs
index fc7ee5629..de4097bc8 100644
--- a/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.IList1Impl.cs
+++ b/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.IList1Impl.cs
@@ -15,10 +15,8 @@
namespace WindowsRuntime.InteropGenerator.Factories;
-///
-/// A factory for interop method definitions.
-///
-internal static partial class InteropMethodDefinitionFactory
+///
+internal partial class InteropMethodDefinitionFactory
{
///
/// Helpers for impl types for interfaces.
diff --git a/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.IReadOnlyDictionary2Impl.cs b/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.IReadOnlyDictionary2Impl.cs
index 1a71cc127..3e20eee50 100644
--- a/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.IReadOnlyDictionary2Impl.cs
+++ b/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.IReadOnlyDictionary2Impl.cs
@@ -14,10 +14,8 @@
namespace WindowsRuntime.InteropGenerator.Factories;
-///
-/// A factory for interop method definitions.
-///
-internal static partial class InteropMethodDefinitionFactory
+///
+internal partial class InteropMethodDefinitionFactory
{
///
/// Helpers for impl types for interfaces.
diff --git a/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.IReadOnlyList1Impl.cs b/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.IReadOnlyList1Impl.cs
index a70f3fcd9..2133d8990 100644
--- a/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.IReadOnlyList1Impl.cs
+++ b/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.IReadOnlyList1Impl.cs
@@ -14,10 +14,8 @@
namespace WindowsRuntime.InteropGenerator.Factories;
-///
-/// A factory for interop method definitions.
-///
-internal static partial class InteropMethodDefinitionFactory
+///
+internal partial class InteropMethodDefinitionFactory
{
///
/// Helpers for impl types for interfaces.
diff --git a/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.SzArrayMarshaller.cs b/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.SzArrayMarshaller.cs
deleted file mode 100644
index a41eb897a..000000000
--- a/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.SzArrayMarshaller.cs
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-
-using AsmResolver.DotNet;
-using AsmResolver.DotNet.Code.Cil;
-using AsmResolver.DotNet.Signatures;
-using AsmResolver.PE.DotNet.Metadata.Tables;
-using WindowsRuntime.InteropGenerator.References;
-using static AsmResolver.PE.DotNet.Cil.CilOpCodes;
-
-namespace WindowsRuntime.InteropGenerator.Factories;
-
-///
-internal partial class InteropMethodDefinitionFactory
-{
- ///
- /// Helpers for marshaller types for SZ array types.
- ///
- public static class SzArrayMarshaller
- {
- ///
- /// Creates a for the Free marshaller method.
- ///
- /// The for the SZ array type.
- /// The instance to use.
- /// The module that will contain the type being created.
- public static MethodDefinition Free(
- SzArrayTypeSignature arrayType,
- InteropReferences interopReferences,
- ModuleDefinition module)
- {
- TypeSignature elementType = arrayType.BaseType;
-
- // Define the 'Free' method as follows:
- //
- // public static void Free(uint size, * destination)
- MethodDefinition freeMethod = new(
- name: "Free"u8,
- attributes: MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig,
- signature: MethodSignature.CreateStatic(
- returnType: module.CorLibTypeFactory.Void,
- parameterTypes: [
- module.CorLibTypeFactory.UInt32,
- elementType.GetAbiType(interopReferences).Import(module).MakePointerType()]));
-
- // For 'string', 'Type', reference types and blittable types, we can reuse the shared stubs from the 'WindowsRuntimeArrayHelpers'
- // type in WinRT.Runtime.dll, to simplify the code and reduce binary size (as we can reuse all these stubs for multiple types).
- if (SignatureComparer.IgnoreVersion.Equals(elementType, interopReferences.CorLibTypeFactory.String))
- {
- freeMethod.CilMethodBody = new CilMethodBody
- {
- Instructions =
- {
- { Ldarg_0 },
- { Ldarg_1 },
- { Call, interopReferences.WindowsRuntimeArrayHelpersFreeHStringArrayUnsafe.Import(module) },
- { Ret }
- }
- };
- }
- else if (SignatureComparer.IgnoreVersion.Equals(elementType, interopReferences.Type))
- {
- freeMethod.CilMethodBody = new CilMethodBody
- {
- Instructions =
- {
- { Ldarg_0 },
- { Ldarg_1 },
- { Call, interopReferences.WindowsRuntimeArrayHelpersFreeTypeArrayUnsafe.Import(module) },
- { Ret }
- }
- };
- }
- else if (!elementType.Resolve()!.IsValueType || elementType.IsConstructedKeyValuePairType(interopReferences))
- {
- freeMethod.CilMethodBody = new CilMethodBody
- {
- Instructions =
- {
- { Ldarg_0 },
- { Ldarg_1 },
- { Call, interopReferences.WindowsRuntimeArrayHelpersFreeObjectArrayUnsafe.Import(module) },
- { Ret }
- }
- };
- }
- else if (elementType.Resolve()!.IsByRefLike) // TODO: check for blittable
- {
- freeMethod.CilMethodBody = new CilMethodBody
- {
- Instructions =
- {
- { Ldarg_0 },
- { Ldarg_1 },
- { Call, interopReferences.WindowsRuntimeArrayHelpersFreeBlittableArrayUnsafe.Import(module) },
- { Ret }
- }
- };
- }
-
- return freeMethod;
- }
- }
-}
\ No newline at end of file
diff --git a/src/WinRT.Interop.Generator/Factories/InteropMethodRewriteFactory.Dispose.cs b/src/WinRT.Interop.Generator/Factories/InteropMethodRewriteFactory.Dispose.cs
new file mode 100644
index 000000000..09b2397e0
--- /dev/null
+++ b/src/WinRT.Interop.Generator/Factories/InteropMethodRewriteFactory.Dispose.cs
@@ -0,0 +1,80 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using AsmResolver.DotNet;
+using AsmResolver.DotNet.Code.Cil;
+using AsmResolver.DotNet.Signatures;
+using AsmResolver.PE.DotNet.Cil;
+using WindowsRuntime.InteropGenerator.Errors;
+using WindowsRuntime.InteropGenerator.Generation;
+using WindowsRuntime.InteropGenerator.References;
+using WindowsRuntime.InteropGenerator.Resolvers;
+using static AsmResolver.PE.DotNet.Cil.CilOpCodes;
+
+namespace WindowsRuntime.InteropGenerator.Factories;
+
+///
+internal partial class InteropMethodRewriteFactory
+{
+ ///
+ /// Contains the logic for disposing (or releasing) a given value (already on the stack).
+ ///
+ public static class Dispose
+ {
+ ///
+ /// Performs two-pass code generation on a target method to dispose (or release) a given value.
+ ///
+ /// The parameter type that needs to be marshalled.
+ /// The target method to perform two-pass code generation on.
+ /// The target IL instruction to replace with the right set of specialized instructions.
+ /// The instance to use.
+ /// The emit state for this invocation.
+ /// The interop module being built.
+ public static void RewriteMethod(
+ TypeSignature parameterType,
+ MethodDefinition method,
+ CilInstruction marker,
+ InteropReferences interopReferences,
+ InteropGeneratorEmitState emitState,
+ ModuleDefinition module)
+ {
+ // Validate that we do have some IL body for the input method (this should always be the case)
+ if (method.CilMethodBody is not CilMethodBody body)
+ {
+ throw WellKnownInteropExceptions.MethodRewriteMissingBodyError(method);
+ }
+
+ // If we didn't find the marker, it means the target method is either invalid
+ if (!body.Instructions.ReferenceContains(marker))
+ {
+ throw WellKnownInteropExceptions.MethodRewriteMarkerInstructionNotFoundError(marker, method);
+ }
+
+ // For unmanaged (or blittable) value types, this call is not valid, as they can't be disposed.
+ // We also need to check whether the type is 'Exception', as its ABI type is blittable as well.
+ if ((parameterType.IsValueType && !parameterType.IsManagedValueType(interopReferences)) || parameterType.IsTypeOfException(interopReferences))
+ {
+ throw WellKnownInteropExceptions.MethodRewriteDisposeNotAvailableError(parameterType, method);
+ }
+
+ // For managed value types, we call 'Dispose' on their marshaller type
+ if (parameterType.IsManagedValueType(interopReferences))
+ {
+ InteropMarshallerType marshallerType = InteropMarshallerTypeResolver.GetMarshallerType(parameterType, interopReferences, emitState);
+
+ body.Instructions.ReferenceReplaceRange(marker, new CilInstruction(Call, marshallerType.Dispose().Import(module)));
+ }
+ else if (parameterType.IsTypeOfString())
+ {
+ // When disposing 'string' values, we must use 'HStringMarshaller' (the ABI type is not actually a COM object)
+ body.Instructions.ReferenceReplaceRange(marker, new CilInstruction(Call, interopReferences.HStringMarshallerFree.Import(module)));
+ }
+ else
+ {
+ // For everything else, we just release the native object. This also applies to generic value types,
+ // such as 'KeyValuePair', because they are actually interface types at the ABI level.
+ body.Instructions.ReferenceReplaceRange(marker, new CilInstruction(Call, interopReferences.WindowsRuntimeUnknownMarshallerFree.Import(module)));
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/WinRT.Interop.Generator/Factories/InteropMethodRewriteFactory.ManagedValue.cs b/src/WinRT.Interop.Generator/Factories/InteropMethodRewriteFactory.ManagedValue.cs
index d4d0fe9b1..881c7e1fc 100644
--- a/src/WinRT.Interop.Generator/Factories/InteropMethodRewriteFactory.ManagedValue.cs
+++ b/src/WinRT.Interop.Generator/Factories/InteropMethodRewriteFactory.ManagedValue.cs
@@ -54,9 +54,11 @@ public static void RewriteMethod(
if (parameterType.IsValueType)
{
- // If the return type is blittable, we have nothing else to do (the value is already loaded)
+ // If the parameter type is blittable, we have nothing else to do (the value is already loaded)
if (parameterType.IsBlittable(interopReferences))
{
+ _ = body.Instructions.ReferenceRemove(marker);
+
return;
}
diff --git a/src/WinRT.Interop.Generator/Factories/InteropMethodRewriteFactory.RawRetVal.cs b/src/WinRT.Interop.Generator/Factories/InteropMethodRewriteFactory.RawRetVal.cs
new file mode 100644
index 000000000..cfad78c8c
--- /dev/null
+++ b/src/WinRT.Interop.Generator/Factories/InteropMethodRewriteFactory.RawRetVal.cs
@@ -0,0 +1,81 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using AsmResolver.DotNet;
+using AsmResolver.DotNet.Code.Cil;
+using AsmResolver.DotNet.Signatures;
+using AsmResolver.PE.DotNet.Cil;
+using WindowsRuntime.InteropGenerator.Errors;
+using WindowsRuntime.InteropGenerator.Generation;
+using WindowsRuntime.InteropGenerator.References;
+using WindowsRuntime.InteropGenerator.Resolvers;
+using static AsmResolver.PE.DotNet.Cil.CilOpCodes;
+
+namespace WindowsRuntime.InteropGenerator.Factories;
+
+///
+internal partial class InteropMethodRewriteFactory
+{
+ ///
+ /// Contains the logic for emitting direct calls to ConvertToUnmanaged for a given value (already on the stack).
+ ///
+ ///
+ /// This is similar to , but without protected regions or any unwrapping.
+ ///
+ public static class RawRetVal
+ {
+ ///
+ /// Performs two-pass code generation on a target method to emit a direct call to ConvertToUnmanaged.
+ ///
+ /// The parameter type that needs to be marshalled.
+ /// The target method to perform two-pass code generation on.
+ /// The target IL instruction to replace with the right set of specialized instructions.
+ /// The instance to use.
+ /// The emit state for this invocation.
+ /// The interop module being built.
+ public static void RewriteMethod(
+ TypeSignature parameterType,
+ MethodDefinition method,
+ CilInstruction marker,
+ InteropReferences interopReferences,
+ InteropGeneratorEmitState emitState,
+ ModuleDefinition module)
+ {
+ // Validate that we do have some IL body for the input method (this should always be the case)
+ // Validate that we do have some IL body for the input method (this should always be thevv case)
+ if (method.CilMethodBody is not CilMethodBody body)
+ {
+ throw WellKnownInteropExceptions.MethodRewriteMissingBodyError(method);
+ }
+
+ // If we didn't find the marker, it means the target method is either invalid
+ if (!body.Instructions.ReferenceContains(marker))
+ {
+ throw WellKnownInteropExceptions.MethodRewriteMarkerInstructionNotFoundError(marker, method);
+ }
+
+ // If the parameter type is blittable, we have nothing else to do (the value is already loaded)
+ if (parameterType.IsBlittable(interopReferences))
+ {
+ _ = body.Instructions.ReferenceRemove(marker);
+
+ return;
+ }
+
+ // For nullable values, we actually need to call 'BoxToUnmanaged'
+ if (parameterType.IsConstructedNullableValueType(interopReferences))
+ {
+ InteropMarshallerType marshallerType = InteropMarshallerTypeResolver.GetMarshallerType(parameterType, interopReferences, emitState);
+
+ body.Instructions.ReferenceReplaceRange(marker, new CilInstruction(Call, marshallerType.BoxToUnmanaged().Import(module)));
+ }
+ else
+ {
+ // For any other types, we always just forward directly to 'ConvertToUnmanaged', without any other changes
+ InteropMarshallerType marshallerType = InteropMarshallerTypeResolver.GetMarshallerType(parameterType, interopReferences, emitState);
+
+ body.Instructions.ReferenceReplaceRange(marker, new CilInstruction(Call, marshallerType.ConvertToUnmanaged().Import(module)));
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/WinRT.Interop.Generator/Factories/InteropTypeDefinitionFactory.SzArrayElementMarshaller.cs b/src/WinRT.Interop.Generator/Factories/InteropTypeDefinitionFactory.SzArrayElementMarshaller.cs
new file mode 100644
index 000000000..75ee7c6a7
--- /dev/null
+++ b/src/WinRT.Interop.Generator/Factories/InteropTypeDefinitionFactory.SzArrayElementMarshaller.cs
@@ -0,0 +1,299 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using AsmResolver.DotNet;
+using AsmResolver.DotNet.Signatures;
+using AsmResolver.PE.DotNet.Cil;
+using AsmResolver.PE.DotNet.Metadata.Tables;
+using WindowsRuntime.InteropGenerator.Generation;
+using WindowsRuntime.InteropGenerator.References;
+using static AsmResolver.PE.DotNet.Cil.CilOpCodes;
+
+namespace WindowsRuntime.InteropGenerator.Factories;
+
+///
+/// A factory for interop type definitions.
+///
+internal partial class InteropTypeDefinitionFactory
+{
+ ///
+ /// Helpers for element marshaller types for SZ array types.
+ ///
+ public static class SzArrayElementMarshaller
+ {
+ ///
+ /// Creates a for the element marshaller for an unmanaged value type.
+ ///
+ /// The for the SZ array type.
+ /// The instance to use.
+ /// The emit state for this invocation.
+ /// The module that will contain the type being created.
+ /// The resulting element marshaller type.
+ public static TypeDefinition UnmanagedValueType(
+ SzArrayTypeSignature arrayType,
+ InteropReferences interopReferences,
+ InteropGeneratorEmitState emitState,
+ ModuleDefinition module)
+ {
+ TypeSignature elementType = arrayType.BaseType;
+ TypeSignature elementAbiType = elementType.GetAbiType(interopReferences);
+
+ // Get the constructed 'IWindowsRuntimeUnmanagedValueTypeArrayElementMarshaller' interface type
+ TypeSignature interfaceType = interopReferences
+ .IWindowsRuntimeUnmanagedValueTypeArrayElementMarshaller2
+ .MakeGenericReferenceType(elementType, elementAbiType);
+
+ return ElementMarshaller(
+ arrayType: arrayType,
+ interfaceType: interfaceType,
+ convertToUnmanagedInterfaceMethod: interopReferences.IWindowsRuntimeUnmanagedValueTypeArrayElementMarshallerConvertToUnmanaged(elementType, elementAbiType),
+ convertToManagedInterfaceMethod: interopReferences.IWindowsRuntimeUnmanagedValueTypeArrayElementMarshallerConvertToManaged(elementType, elementAbiType),
+ isValueType: true,
+ interopReferences: interopReferences,
+ emitState: emitState,
+ module: module);
+ }
+
+ ///
+ /// Creates a for the element marshaller for a managed value type.
+ ///
+ /// The for the SZ array type.
+ /// The instance to use.
+ /// The emit state for this invocation.
+ /// The module that will contain the type being created.
+ /// The resulting element marshaller type.
+ public static TypeDefinition ManagedValueType(
+ SzArrayTypeSignature arrayType,
+ InteropReferences interopReferences,
+ InteropGeneratorEmitState emitState,
+ ModuleDefinition module)
+ {
+ TypeSignature elementType = arrayType.BaseType;
+ TypeSignature elementAbiType = elementType.GetAbiType(interopReferences);
+
+ // Get the constructed 'IWindowsRuntimeManagedValueTypeArrayElementMarshaller' interface type
+ TypeSignature interfaceType = interopReferences
+ .IWindowsRuntimeManagedValueTypeArrayElementMarshaller2
+ .MakeGenericReferenceType(elementType, elementAbiType);
+
+ // Get the element marshaller type with the common method implementations
+ TypeDefinition elementMarshallerType = ElementMarshaller(
+ arrayType: arrayType,
+ interfaceType: interfaceType,
+ convertToUnmanagedInterfaceMethod: interopReferences.IWindowsRuntimeManagedValueTypeArrayElementMarshallerConvertToUnmanaged(elementType, elementAbiType),
+ convertToManagedInterfaceMethod: interopReferences.IWindowsRuntimeManagedValueTypeArrayElementMarshallerConvertToManaged(elementType, elementAbiType),
+ isValueType: true,
+ interopReferences: interopReferences,
+ emitState: emitState,
+ module: module);
+
+ // Rewriting labels
+ CilInstruction nop_dispose = new(Nop);
+
+ // Define the 'Dispose' method as follows:
+ //
+ // public static void Dispose( value)
+ MethodDefinition disposeMethod = new(
+ name: "Dispose"u8,
+ attributes: MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig,
+ signature: MethodSignature.CreateStatic(module.CorLibTypeFactory.Void, elementAbiType.Import(module)))
+ {
+ CilInstructions =
+ {
+ { Ldarg_0 },
+ { nop_dispose },
+ { Ret }
+ }
+ };
+
+ // Add and implement the 'Dispose' method
+ elementMarshallerType.AddMethodImplementation(
+ declaration: interopReferences.IWindowsRuntimeManagedValueTypeArrayElementMarshallerDispose(elementType, elementAbiType).Import(module),
+ method: disposeMethod);
+
+ // Track rewriting the disposal for 'Dispose'
+ emitState.TrackDisposeRewrite(
+ parameterType: elementType,
+ method: disposeMethod,
+ marker: nop_dispose);
+
+ return elementMarshallerType;
+ }
+
+ ///
+ /// Creates a for the element marshaller for a type.
+ ///
+ /// The for the SZ array type.
+ /// The instance to use.
+ /// The emit state for this invocation.
+ /// The module that will contain the type being created.
+ /// The resulting element marshaller type.
+ public static TypeDefinition KeyValuePair(
+ SzArrayTypeSignature arrayType,
+ InteropReferences interopReferences,
+ InteropGeneratorEmitState emitState,
+ ModuleDefinition module)
+ {
+ GenericInstanceTypeSignature elementType = (GenericInstanceTypeSignature)arrayType.BaseType;
+ TypeSignature keyType = elementType.TypeArguments[0];
+ TypeSignature valueType = elementType.TypeArguments[1];
+
+ // Get the constructed 'IWindowsRuntimeKeyValuePairTypeArrayElementMarshaller' interface type
+ TypeSignature interfaceType = interopReferences
+ .IWindowsRuntimeKeyValuePairTypeArrayElementMarshaller2
+ .MakeGenericReferenceType(keyType, valueType);
+
+ // If both the key and the value types are value types, it means the whole marshaller will be specialized.
+ // In that case we can emit the element marshaller type as a value type as well, so the whole thing can be
+ // fully specialized and inlined. We don't do this if either type is a reference type, because that means
+ // the generic instantiation could still be shared between different types, so we prefer to save size there.
+ bool isValueType = keyType.IsValueType && valueType.IsValueType;
+
+ return ElementMarshaller(
+ arrayType: arrayType,
+ interfaceType: interfaceType,
+ convertToUnmanagedInterfaceMethod: interopReferences.IWindowsRuntimeKeyValuePairTypeArrayElementMarshallerConvertToUnmanaged(keyType, valueType),
+ convertToManagedInterfaceMethod: interopReferences.IWindowsRuntimeKeyValuePairTypeArrayElementMarshallerConvertToManaged(keyType, valueType),
+ isValueType: isValueType,
+ interopReferences: interopReferences,
+ emitState: emitState,
+ module: module);
+ }
+
+ ///
+ /// Creates a for the element marshaller for a reference type.
+ ///
+ /// The for the SZ array type.
+ /// The instance to use.
+ /// The emit state for this invocation.
+ /// The module that will contain the type being created.
+ /// The resulting element marshaller type.
+ public static TypeDefinition ReferenceType(
+ SzArrayTypeSignature arrayType,
+ InteropReferences interopReferences,
+ InteropGeneratorEmitState emitState,
+ ModuleDefinition module)
+ {
+ TypeSignature elementType = arrayType.BaseType;
+
+ // Get the constructed 'IWindowsRuntimeReferenceTypeArrayElementMarshaller' interface type
+ TypeSignature interfaceType = interopReferences
+ .IWindowsRuntimeReferenceTypeArrayElementMarshaller1
+ .MakeGenericReferenceType(elementType);
+
+ return ElementMarshaller(
+ arrayType: arrayType,
+ interfaceType: interfaceType,
+ convertToUnmanagedInterfaceMethod: interopReferences.IWindowsRuntimeReferenceTypeArrayElementMarshallerConvertToUnmanaged(elementType),
+ convertToManagedInterfaceMethod: interopReferences.IWindowsRuntimeReferenceTypeArrayElementMarshallerConvertToManaged(elementType),
+ isValueType: false,
+ interopReferences: interopReferences,
+ emitState: emitState,
+ module: module);
+ }
+
+ ///
+ /// Creates a for the element marshaller for some element type.
+ ///
+ /// The for the SZ array type.
+ /// The interface type the element marshaller type should implement.
+ /// The ConvertToUnmanaged interface method being implemented.
+ /// The ConvertToManaged interface method being implemented.
+ /// Indicates whether the element marshaller type should be emitted as a value type.
+ /// The instance to use.
+ /// The emit state for this invocation.
+ /// The module that will contain the type being created.
+ /// The resulting element marshaller type.
+ public static TypeDefinition ElementMarshaller(
+ SzArrayTypeSignature arrayType,
+ TypeSignature interfaceType,
+ MemberReference convertToUnmanagedInterfaceMethod,
+ MemberReference convertToManagedInterfaceMethod,
+ bool isValueType,
+ InteropReferences interopReferences,
+ InteropGeneratorEmitState emitState,
+ ModuleDefinition module)
+ {
+ TypeSignature elementType = arrayType.BaseType;
+
+ // Select the attributes and base type depending on whether we want a value type or not
+ (TypeAttributes attributes, ITypeDefOrRef baseType) = isValueType
+ ? (TypeAttributes.SequentialLayout | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, interopReferences.ValueType)
+ : (TypeAttributes.AutoLayout | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, module.CorLibTypeFactory.Object.ToTypeDefOrRef());
+
+ // We're declaring an 'internal abstract class' type
+ TypeDefinition elementMarshallerType = new(
+ ns: InteropUtf8NameFactory.TypeNamespace(arrayType),
+ name: InteropUtf8NameFactory.TypeName(arrayType, "ElementMarshaller"),
+ attributes: attributes,
+ baseType: baseType)
+ {
+ Interfaces = { new InterfaceImplementation(interfaceType.Import(module).ToTypeDefOrRef()) }
+ };
+
+ // Rewriting labels
+ CilInstruction nop_convertToUnmanaged = new(Nop);
+ CilInstruction nop_convertToManaged = new(Nop);
+
+ // Define the 'ConvertToUnmanaged' method as follows:
+ //
+ // public static ConvertToUnmanaged( value)
+ MethodDefinition convertToUnmanagedMethod = new(
+ name: "ConvertToUnmanaged"u8,
+ attributes: MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig,
+ signature: MethodSignature.CreateStatic(
+ returnType: elementType.GetRawAbiType(interopReferences).Import(module),
+ parameterTypes: [elementType.Import(module)]))
+ {
+ CilInstructions =
+ {
+ { Ldarg_0 },
+ { nop_convertToUnmanaged },
+ { Ret }
+ }
+ };
+
+ // Add and implement the 'ConvertToUnmanaged' method
+ elementMarshallerType.AddMethodImplementation(
+ declaration: convertToUnmanagedInterfaceMethod.Import(module),
+ method: convertToUnmanagedMethod);
+
+ // Track rewriting the native value for 'ConvertToUnmanaged'
+ emitState.TrackRawRetValMethodRewrite(
+ parameterType: elementType,
+ method: convertToUnmanagedMethod,
+ marker: nop_convertToUnmanaged);
+
+ // Define the 'ConvertToManaged' method as follows:
+ //
+ // public static ConvertToManaged( value)
+ MethodDefinition convertToManagedMethod = new(
+ name: "ConvertToManaged"u8,
+ attributes: MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig,
+ signature: MethodSignature.CreateStatic(
+ returnType: elementType.Import(module),
+ parameterTypes: [elementType.GetAbiType(interopReferences).Import(module)]))
+ {
+ CilInstructions =
+ {
+ { nop_convertToManaged },
+ { Ret }
+ }
+ };
+
+ // Add and implement the 'ConvertToManaged' method
+ elementMarshallerType.AddMethodImplementation(
+ declaration: convertToManagedInterfaceMethod.Import(module),
+ method: convertToManagedMethod);
+
+ // Track rewriting the managed value for 'ConvertToManaged'
+ emitState.TrackManagedParameterMethodRewrite(
+ parameterType: elementType,
+ method: convertToManagedMethod,
+ marker: nop_convertToManaged,
+ parameterIndex: 0);
+
+ return elementMarshallerType;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/WinRT.Interop.Generator/Factories/InteropTypeDefinitionFactory.SzArrayMarshaller.cs b/src/WinRT.Interop.Generator/Factories/InteropTypeDefinitionFactory.SzArrayMarshaller.cs
new file mode 100644
index 000000000..ff7843205
--- /dev/null
+++ b/src/WinRT.Interop.Generator/Factories/InteropTypeDefinitionFactory.SzArrayMarshaller.cs
@@ -0,0 +1,389 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using AsmResolver.DotNet;
+using AsmResolver.DotNet.Signatures;
+using AsmResolver.PE.DotNet.Metadata.Tables;
+using WindowsRuntime.InteropGenerator.References;
+using static AsmResolver.PE.DotNet.Cil.CilOpCodes;
+
+namespace WindowsRuntime.InteropGenerator.Factories;
+
+///
+/// A factory for interop type definitions.
+///
+internal partial class InteropTypeDefinitionFactory
+{
+ ///
+ /// Helpers for marshaller types for SZ array types.
+ ///
+ public static class SzArrayMarshaller
+ {
+ ///
+ /// Creates a for the marshaller for a blittable value type.
+ ///
+ /// The for the SZ array type.
+ /// The instance to use.
+ /// The module that will contain the type being created.
+ /// The resulting marshaller type.
+ public static TypeDefinition BlittableValueType(
+ SzArrayTypeSignature arrayType,
+ InteropReferences interopReferences,
+ ModuleDefinition module)
+ {
+ TypeSignature elementType = arrayType.BaseType;
+
+ return Marshaller(
+ arrayType: arrayType,
+ convertToUnmanagedMethod: interopReferences.WindowsRuntimeBlittableValueTypeArrayMarshallerConvertToUnmanaged(elementType),
+ convertToManagedMethod: interopReferences.WindowsRuntimeBlittableValueTypeArrayMarshallerConvertToManaged(elementType),
+ copyToUnmanagedMethod: interopReferences.WindowsRuntimeBlittableValueTypeArrayMarshallerCopyToUnmanaged(elementType),
+ copyToManagedMethod: interopReferences.WindowsRuntimeBlittableValueTypeArrayMarshallerCopyToManaged(elementType),
+ freeMethod: interopReferences.WindowsRuntimeBlittableValueTypeArrayMarshallerFree(elementType),
+ interopReferences: interopReferences,
+ module: module);
+ }
+
+ ///
+ /// Creates a for the marshaller for an unmanaged value type.
+ ///
+ /// The for the SZ array type.
+ /// The element marshaller type produced by .
+ /// The instance to use.
+ /// The module that will contain the type being created.
+ /// The resulting marshaller type.
+ public static TypeDefinition UnmanagedValueType(
+ SzArrayTypeSignature arrayType,
+ TypeDefinition elementMarshallerType,
+ InteropReferences interopReferences,
+ ModuleDefinition module)
+ {
+ TypeSignature elementType = arrayType.BaseType;
+ TypeSignature elementAbiType = elementType.GetAbiType(interopReferences);
+ TypeSignature elementMarshallerTypeSignature = elementMarshallerType.ToTypeSignature();
+
+ return Marshaller(
+ arrayType: arrayType,
+ convertToUnmanagedMethod: interopReferences.WindowsRuntimeUnmanagedValueTypeArrayMarshallerConvertToUnmanaged(elementType, elementAbiType, elementMarshallerTypeSignature),
+ convertToManagedMethod: interopReferences.WindowsRuntimeUnmanagedValueTypeArrayMarshallerConvertToManaged(elementType, elementAbiType, elementMarshallerTypeSignature),
+ copyToUnmanagedMethod: interopReferences.WindowsRuntimeUnmanagedValueTypeArrayMarshallerCopyToUnmanaged(elementType, elementAbiType, elementMarshallerTypeSignature),
+ copyToManagedMethod: interopReferences.WindowsRuntimeUnmanagedValueTypeArrayMarshallerCopyToManaged(elementType, elementAbiType, elementMarshallerTypeSignature),
+ freeMethod: interopReferences.WindowsRuntimeUnmanagedValueTypeArrayMarshallerFree(elementType, elementAbiType),
+ interopReferences: interopReferences,
+ module: module);
+ }
+
+ ///
+ /// Creates a for the marshaller for a managed value type.
+ ///
+ /// The for the SZ array type.
+ /// The element marshaller type produced by .
+ /// The instance to use.
+ /// The module that will contain the type being created.
+ /// The resulting marshaller type.
+ public static TypeDefinition ManagedValueType(
+ SzArrayTypeSignature arrayType,
+ TypeDefinition elementMarshallerType,
+ InteropReferences interopReferences,
+ ModuleDefinition module)
+ {
+ TypeSignature elementType = arrayType.BaseType;
+ TypeSignature elementAbiType = elementType.GetAbiType(interopReferences);
+ TypeSignature elementMarshallerTypeSignature = elementMarshallerType.ToTypeSignature();
+
+ return Marshaller(
+ arrayType: arrayType,
+ convertToUnmanagedMethod: interopReferences.WindowsRuntimeManagedValueTypeArrayMarshallerConvertToUnmanaged(elementType, elementAbiType, elementMarshallerTypeSignature),
+ convertToManagedMethod: interopReferences.WindowsRuntimeManagedValueTypeArrayMarshallerConvertToManaged(elementType, elementAbiType, elementMarshallerTypeSignature),
+ copyToUnmanagedMethod: interopReferences.WindowsRuntimeManagedValueTypeArrayMarshallerCopyToUnmanaged(elementType, elementAbiType, elementMarshallerTypeSignature),
+ copyToManagedMethod: interopReferences.WindowsRuntimeManagedValueTypeArrayMarshallerCopyToManaged(elementType, elementAbiType, elementMarshallerTypeSignature),
+ freeMethod: interopReferences.WindowsRuntimeManagedValueTypeArrayMarshallerFree(elementType, elementAbiType, elementMarshallerTypeSignature),
+ interopReferences: interopReferences,
+ module: module);
+ }
+
+ ///
+ /// Creates a for the marshaller for a type.
+ ///
+ /// The for the SZ array type.
+ /// The element marshaller type produced by .
+ /// The instance to use.
+ /// The module that will contain the type being created.
+ /// The resulting marshaller type.
+ public static TypeDefinition KeyValuePair(
+ SzArrayTypeSignature arrayType,
+ TypeDefinition elementMarshallerType,
+ InteropReferences interopReferences,
+ ModuleDefinition module)
+ {
+ GenericInstanceTypeSignature elementType = (GenericInstanceTypeSignature)arrayType.BaseType;
+ TypeSignature keyType = elementType.TypeArguments[0];
+ TypeSignature valueType = elementType.TypeArguments[1];
+ TypeSignature elementMarshallerTypeSignature = elementMarshallerType.ToTypeSignature();
+
+ return Marshaller(
+ arrayType: arrayType,
+ convertToUnmanagedMethod: interopReferences.WindowsRuntimeKeyValuePairTypeArrayMarshallerConvertToUnmanaged(keyType, valueType, elementMarshallerTypeSignature),
+ convertToManagedMethod: interopReferences.WindowsRuntimeKeyValuePairTypeArrayMarshallerConvertToManaged(keyType, valueType, elementMarshallerTypeSignature),
+ copyToUnmanagedMethod: interopReferences.WindowsRuntimeKeyValuePairTypeArrayMarshallerCopyToUnmanaged(keyType, valueType, elementMarshallerTypeSignature),
+ copyToManagedMethod: interopReferences.WindowsRuntimeKeyValuePairTypeArrayMarshallerCopyToManaged(keyType, valueType, elementMarshallerTypeSignature),
+ freeMethod: interopReferences.WindowsRuntimeUnknownArrayMarshallerFree,
+ interopReferences: interopReferences,
+ module: module);
+ }
+
+ ///
+ /// Creates a for the marshaller for a reference type.
+ ///
+ /// The for the SZ array type.
+ /// The element marshaller type produced by .
+ /// The instance to use.
+ /// The module that will contain the type being created.
+ /// The resulting marshaller type.
+ public static TypeDefinition ReferenceType(
+ SzArrayTypeSignature arrayType,
+ TypeDefinition elementMarshallerType,
+ InteropReferences interopReferences,
+ ModuleDefinition module)
+ {
+ TypeSignature elementType = arrayType.BaseType;
+ TypeSignature elementMarshallerTypeSignature = elementMarshallerType.ToTypeSignature();
+
+ return Marshaller(
+ arrayType: arrayType,
+ convertToUnmanagedMethod: interopReferences.WindowsRuntimeReferenceTypeArrayMarshallerConvertToUnmanaged(elementType, elementMarshallerTypeSignature),
+ convertToManagedMethod: interopReferences.WindowsRuntimeReferenceTypeArrayMarshallerConvertToManaged(elementType, elementMarshallerTypeSignature),
+ copyToUnmanagedMethod: interopReferences.WindowsRuntimeReferenceTypeArrayMarshallerCopyToUnmanaged(elementType, elementMarshallerTypeSignature),
+ copyToManagedMethod: interopReferences.WindowsRuntimeReferenceTypeArrayMarshallerCopyToManaged(elementType, elementMarshallerTypeSignature),
+ freeMethod: interopReferences.WindowsRuntimeUnknownArrayMarshallerFree,
+ interopReferences: interopReferences,
+ module: module);
+ }
+
+ ///
+ /// Creates a for the marshaller for the type.
+ ///
+ /// The for the SZ array type.
+ /// The instance to use.
+ /// The module that will contain the type being created.
+ /// The resulting marshaller type.
+ public static TypeDefinition String(
+ SzArrayTypeSignature arrayType,
+ InteropReferences interopReferences,
+ ModuleDefinition module)
+ {
+ return Marshaller(
+ arrayType: arrayType,
+ convertToUnmanagedMethod: interopReferences.HStringArrayMarshallerConvertToUnmanaged,
+ convertToManagedMethod: interopReferences.HStringArrayMarshallerConvertToManaged,
+ copyToUnmanagedMethod: interopReferences.HStringArrayMarshallerCopyToUnmanaged,
+ copyToManagedMethod: interopReferences.HStringArrayMarshallerCopyToManaged,
+ freeMethod: interopReferences.HStringArrayMarshallerFree,
+ interopReferences: interopReferences,
+ module: module);
+ }
+
+ ///
+ /// Creates a for the marshaller for the type.
+ ///
+ /// The for the SZ array type.
+ /// The instance to use.
+ /// The module that will contain the type being created.
+ /// The resulting marshaller type.
+ public static TypeDefinition Type(
+ SzArrayTypeSignature arrayType,
+ InteropReferences interopReferences,
+ ModuleDefinition module)
+ {
+ return Marshaller(
+ arrayType: arrayType,
+ convertToUnmanagedMethod: interopReferences.TypeArrayMarshallerConvertToUnmanaged,
+ convertToManagedMethod: interopReferences.TypeArrayMarshallerConvertToManaged,
+ copyToUnmanagedMethod: interopReferences.TypeArrayMarshallerCopyToUnmanaged,
+ copyToManagedMethod: interopReferences.TypeArrayMarshallerCopyToManaged,
+ freeMethod: interopReferences.TypeArrayMarshallerFree,
+ interopReferences: interopReferences,
+ module: module);
+ }
+
+ ///
+ /// Creates a for the marshaller for the type.
+ ///
+ /// The for the SZ array type.
+ /// The instance to use.
+ /// The module that will contain the type being created.
+ /// The resulting marshaller type.
+ public static TypeDefinition Exception(
+ SzArrayTypeSignature arrayType,
+ InteropReferences interopReferences,
+ ModuleDefinition module)
+ {
+ return Marshaller(
+ arrayType: arrayType,
+ convertToUnmanagedMethod: interopReferences.ExceptionArrayMarshallerConvertToUnmanaged,
+ convertToManagedMethod: interopReferences.ExceptionArrayMarshallerConvertToManaged,
+ copyToUnmanagedMethod: interopReferences.ExceptionArrayMarshallerCopyToUnmanaged,
+ copyToManagedMethod: interopReferences.ExceptionArrayMarshallerCopyToManaged,
+ freeMethod: interopReferences.ExceptionArrayMarshallerFree,
+ interopReferences: interopReferences,
+ module: module);
+ }
+
+ ///
+ /// Creates a new type definition for the marshaller for some SZ array type.
+ ///
+ /// The for the SZ array type.
+ /// The ConvertToUnmanaged implementation method to call.
+ /// The ConvertToManaged implementation method to call.
+ /// The CopyToUnmanaged implementation method to call.
+ /// The CopyToManaged implementation method to call.
+ /// The Free implementation method to call.
+ /// The instance to use.
+ /// The module that will contain the type being created.
+ /// The resulting marshaller type.
+ private static TypeDefinition Marshaller(
+ SzArrayTypeSignature arrayType,
+ IMethodDescriptor convertToUnmanagedMethod,
+ IMethodDescriptor convertToManagedMethod,
+ IMethodDescriptor copyToUnmanagedMethod,
+ IMethodDescriptor copyToManagedMethod,
+ IMethodDescriptor freeMethod,
+ InteropReferences interopReferences,
+ ModuleDefinition module)
+ {
+ TypeSignature elementType = arrayType.BaseType;
+ TypeSignature elementAbiType = elementType.GetAbiType(interopReferences);
+
+ // We're declaring an 'internal static class' type
+ TypeDefinition marshallerType = new(
+ ns: InteropUtf8NameFactory.TypeNamespace(arrayType),
+ name: InteropUtf8NameFactory.TypeName(arrayType, "Marshaller"),
+ attributes: TypeAttributes.AutoLayout | TypeAttributes.Sealed | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit,
+ baseType: module.CorLibTypeFactory.Object.ToTypeDefOrRef());
+
+ // Define the 'ConvertToUnmanaged' method as follows:
+ //
+ // public static void ConvertToUnmanaged(ReadOnlySpan<>, out uint size, out * array)
+ MethodDefinition convertToUnmanagedForwarderMethod = new(
+ name: "ConvertToUnmanaged"u8,
+ attributes: MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig,
+ signature: MethodSignature.CreateStatic(
+ returnType: module.CorLibTypeFactory.Void,
+ parameterTypes: [
+ interopReferences.ReadOnlySpan1.MakeGenericValueType(elementType).Import(module),
+ module.CorLibTypeFactory.UInt32.MakeByReferenceType(),
+ elementAbiType.Import(module).MakePointerType().MakeByReferenceType()]))
+ {
+ CilOutParameterIndices = [2, 3],
+ CilInstructions =
+ {
+ { Ldarg_0 },
+ { Ldarg_1 },
+ { Ldarg_2 },
+ { Call, convertToUnmanagedMethod.Import(module) },
+ { Ret }
+ }
+ };
+
+ marshallerType.Methods.Add(convertToUnmanagedForwarderMethod);
+
+ // Define the 'ConvertToManaged' method as follows:
+ //
+ // public static [] ConvertToManaged(uint size, * value)
+ MethodDefinition convertToManagedForwarderMethod = new(
+ name: "ConvertToManaged"u8,
+ attributes: MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig,
+ signature: MethodSignature.CreateStatic(
+ returnType: arrayType.Import(module),
+ parameterTypes: [
+ module.CorLibTypeFactory.UInt32,
+ elementAbiType.Import(module).MakePointerType()]))
+ {
+ CilInstructions =
+ {
+ { Ldarg_0 },
+ { Ldarg_1 },
+ { Call, convertToManagedMethod.Import(module) },
+ { Ret }
+ }
+ };
+
+ marshallerType.Methods.Add(convertToManagedForwarderMethod);
+
+ // Define the 'CopyToManaged' method as follows:
+ //
+ // public static void CopyToManaged(uint size, * value, Span<> destination)
+ MethodDefinition copyToManagedForwarderMethod = new(
+ name: "CopyToManaged"u8,
+ attributes: MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig,
+ signature: MethodSignature.CreateStatic(
+ returnType: module.CorLibTypeFactory.Void,
+ parameterTypes: [
+ module.CorLibTypeFactory.UInt32,
+ elementAbiType.Import(module).MakePointerType(),
+ interopReferences.Span1.MakeGenericValueType(elementType).Import(module)]))
+ {
+ CilInstructions =
+ {
+ { Ldarg_0 },
+ { Ldarg_1 },
+ { Ldarg_2 },
+ { Call, copyToManagedMethod.Import(module) },
+ { Ret }
+ }
+ };
+
+ marshallerType.Methods.Add(copyToManagedForwarderMethod);
+
+ // Define the 'CopyToUnmanaged' method as follows:
+ //
+ // public static void CopyToUnmanaged(ReadOnlySpan<> value, uint size, * destination)
+ MethodDefinition copyToUnmanagedForwarderMethod = new(
+ name: "CopyToUnmanaged"u8,
+ attributes: MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig,
+ signature: MethodSignature.CreateStatic(
+ returnType: module.CorLibTypeFactory.Void,
+ parameterTypes: [
+ interopReferences.ReadOnlySpan1.MakeGenericValueType(elementType).Import(module),
+ module.CorLibTypeFactory.UInt32,
+ elementAbiType.Import(module).MakePointerType()]))
+ {
+ CilInstructions =
+ {
+ { Ldarg_0 },
+ { Ldarg_1 },
+ { Ldarg_2 },
+ { Call, copyToUnmanagedMethod.Import(module) },
+ { Ret }
+ }
+ };
+
+ marshallerType.Methods.Add(copyToUnmanagedForwarderMethod);
+
+ // Define the 'Free' method as follows:
+ //
+ // public static void Free(uint size, * destination)
+ MethodDefinition freeForwarderMethod = new(
+ name: "Free"u8,
+ attributes: MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig,
+ signature: MethodSignature.CreateStatic(
+ returnType: module.CorLibTypeFactory.Void,
+ parameterTypes: [
+ module.CorLibTypeFactory.UInt32,
+ elementAbiType.Import(module).MakePointerType()]))
+ {
+ CilInstructions =
+ {
+ { Ldarg_0 },
+ { Ldarg_1 },
+ { Call, freeMethod.Import(module) },
+ { Ret }
+ }
+ };
+
+ marshallerType.Methods.Add(freeForwarderMethod);
+
+ return marshallerType;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/WinRT.Interop.Generator/Factories/InteropUtf8NameFactory.cs b/src/WinRT.Interop.Generator/Factories/InteropUtf8NameFactory.cs
index 10b05f77b..fd47ba213 100644
--- a/src/WinRT.Interop.Generator/Factories/InteropUtf8NameFactory.cs
+++ b/src/WinRT.Interop.Generator/Factories/InteropUtf8NameFactory.cs
@@ -74,62 +74,41 @@ static void AppendTypeName(
return;
}
- // SZ arrays are enclosed in angle brackets
- if (typeSignature is SzArrayTypeSignature)
+ // SZ arrays are enclosed in angle brackets, and have the 'Array' suffix at the end
+ if (typeSignature is SzArrayTypeSignature arrayTypeSignature)
{
interpolatedStringHandler.AppendLiteral("<");
- }
- // Each type name uses this format: 'TYPE_NAME'
- interpolatedStringHandler.AppendLiteral("<");
- interpolatedStringHandler.AppendFormatted(AssemblyNameOrWellKnownIdentifier(typeSignature.Scope!.GetAssembly()!.Name, typeSignature));
- interpolatedStringHandler.AppendLiteral(">");
+ AppendTypeName(ref interpolatedStringHandler, arrayTypeSignature.BaseType, depth);
- // If the type is generic, append the definition name and the type arguments
- if (typeSignature is GenericInstanceTypeSignature genericInstanceTypeSignature)
+ interpolatedStringHandler.AppendLiteral(">Array");
+ }
+ else
{
- // Append the name of the generic type, without any type arguments (those are appended below)
- AppendRawTypeName(ref interpolatedStringHandler, genericInstanceTypeSignature.GenericType, depth);
-
+ // Each type name uses this format: 'TYPE_NAME'
interpolatedStringHandler.AppendLiteral("<");
+ interpolatedStringHandler.AppendFormatted(AssemblyNameOrWellKnownIdentifier(typeSignature.Scope!.GetAssembly()!.Name, typeSignature));
+ interpolatedStringHandler.AppendLiteral(">");
- foreach ((int i, TypeSignature typeArgumentSignature) in genericInstanceTypeSignature.TypeArguments.Index())
- {
- // We use '|' to separate generic type arguments
- if (i > 0)
- {
- interpolatedStringHandler.AppendLiteral("|");
- }
-
- // Append the type argument with the same format as the root type. This is
- // important to ensure that nested generic types will be handled correctly.
- AppendTypeName(ref interpolatedStringHandler, typeArgumentSignature, depth: depth + 1);
- }
+ // Extract the generic type if we have a generic signature, or use the type signature directly
+ ITypeDescriptor originalTypeDescriptor = ((typeSignature as GenericInstanceTypeSignature)?.GenericType) ?? (ITypeDescriptor)typeSignature;
- interpolatedStringHandler.AppendLiteral(">");
- }
- else if (typeSignature is SzArrayTypeSignature arrayTypeSignature)
- {
- // Same as below, but we use the element type name, not the array type name
- AppendRawTypeName(ref interpolatedStringHandler, arrayTypeSignature.BaseType, depth);
- }
- else
- {
- // Simple case for normal type signatures
- AppendRawTypeName(ref interpolatedStringHandler, typeSignature, depth);
- }
+ // Append the original type name first, regardless of whether it's an array or a constructed generic
+ AppendRawTypeName(ref interpolatedStringHandler, originalTypeDescriptor, depth);
- // Complete the name mangling for SZ arrays
- if (typeSignature is SzArrayTypeSignature)
- {
- interpolatedStringHandler.AppendLiteral(">Array");
+ // If the type is generic, append the definition name and the type arguments. We pass the original
+ // type descriptor here, because we also want to detect arrays with an element type that's generic.
+ if (typeSignature is GenericInstanceTypeSignature genericInstanceTypeSignature)
+ {
+ AppendTypeArguments(ref interpolatedStringHandler, genericInstanceTypeSignature, depth);
+ }
}
}
// Helper to recursively build the type name (to handle nested generic types too)
static void AppendRawTypeName(
ref DefaultInterpolatedStringHandler interpolatedStringHandler,
- IMemberDescriptor type,
+ ITypeDescriptor type,
int depth)
{
// We can skip the namespace when the indentation level is '0', as that means
@@ -166,6 +145,30 @@ static void AppendRawTypeName(
}
}
+ // Helper to iteratively print the type arguments for a constructed type
+ static void AppendTypeArguments(
+ ref DefaultInterpolatedStringHandler interpolatedStringHandler,
+ GenericInstanceTypeSignature type,
+ int depth)
+ {
+ interpolatedStringHandler.AppendLiteral("<");
+
+ foreach ((int i, TypeSignature typeArgumentSignature) in type.TypeArguments.Index())
+ {
+ // We use '|' to separate generic type arguments
+ if (i > 0)
+ {
+ interpolatedStringHandler.AppendLiteral("|");
+ }
+
+ // Append the type argument with the same format as the root type. This is
+ // important to ensure that nested generic types will be handled correctly.
+ AppendTypeName(ref interpolatedStringHandler, typeArgumentSignature, depth: depth + 1);
+ }
+
+ interpolatedStringHandler.AppendLiteral(">");
+ }
+
// Append the full type name first
AppendTypeName(ref interpolatedStringHandler, typeSignature, depth: 0);
diff --git a/src/WinRT.Interop.Generator/Generation/InteropGenerator.Emit.cs b/src/WinRT.Interop.Generator/Generation/InteropGenerator.Emit.cs
index 4a92f1f3c..260bf0324 100644
--- a/src/WinRT.Interop.Generator/Generation/InteropGenerator.Emit.cs
+++ b/src/WinRT.Interop.Generator/Generation/InteropGenerator.Emit.cs
@@ -135,7 +135,7 @@ private static void Emit(InteropGeneratorArgs args, InteropGeneratorDiscoverySta
args.Token.ThrowIfCancellationRequested();
// Emit interop types for SZ array types
- DefineSzArrayTypes(args, discoveryState, interopDefinitions, interopReferences, module);
+ DefineSzArrayTypes(args, discoveryState, emitState, interopDefinitions, interopReferences, module);
args.Token.ThrowIfCancellationRequested();
@@ -1905,12 +1905,14 @@ private static void DefineIAsyncOperationWithProgressTypes(
///
///
///
+ /// The emit state for this invocation.
/// The instance to use.
/// The instance to use.
/// The interop module being built.
private static void DefineSzArrayTypes(
InteropGeneratorArgs args,
InteropGeneratorDiscoveryState discoveryState,
+ InteropGeneratorEmitState emitState,
InteropDefinitions interopDefinitions,
InteropReferences interopReferences,
ModuleDefinition module)
@@ -1932,6 +1934,7 @@ private static void DefineSzArrayTypes(
InteropTypeDefinitionBuilder.SzArray.Marshaller(
arrayType: typeSignature,
interopReferences: interopReferences,
+ emitState: emitState,
module: module,
marshallerType: out TypeDefinition marshallerType);
@@ -2017,6 +2020,17 @@ private static void RewriteMethodDefinitions(
{
switch (rewriteInfo)
{
+ // Rewrite direct calls to 'ConvertToUnmanaged' (or 'BoxToUnmanaged')
+ case MethodRewriteInfo.RawRetVal rawRetValInfo:
+ InteropMethodRewriteFactory.RawRetVal.RewriteMethod(
+ parameterType: rawRetValInfo.Type,
+ method: rawRetValInfo.Method,
+ marker: rawRetValInfo.Marker,
+ interopReferences: interopReferences,
+ emitState: emitState,
+ module: module);
+ break;
+
// Rewrite return values for managed types
case MethodRewriteInfo.ReturnValue returnValueInfo:
InteropMethodRewriteFactory.ReturnValue.RewriteMethod(
@@ -2076,6 +2090,17 @@ private static void RewriteMethodDefinitions(
emitState: emitState,
module: module);
break;
+
+ // Rewrite direct calls to 'Dispose' (or the appropriate 'Free' method)
+ case MethodRewriteInfo.Dispose disposeInfo:
+ InteropMethodRewriteFactory.Dispose.RewriteMethod(
+ parameterType: disposeInfo.Type,
+ method: disposeInfo.Method,
+ marker: disposeInfo.Marker,
+ interopReferences: interopReferences,
+ emitState: emitState,
+ module: module);
+ break;
default: throw new UnreachableException();
}
}
diff --git a/src/WinRT.Interop.Generator/Generation/InteropGeneratorEmitState.cs b/src/WinRT.Interop.Generator/Generation/InteropGeneratorEmitState.cs
index 1009530b2..495204504 100644
--- a/src/WinRT.Interop.Generator/Generation/InteropGeneratorEmitState.cs
+++ b/src/WinRT.Interop.Generator/Generation/InteropGeneratorEmitState.cs
@@ -132,6 +132,27 @@ public void TrackRetValValueMethodRewrite(
});
}
+ ///
+ /// Tracks a method rewrite that involves emitting direct calls to ConvertToUnmanaged in the specified method.
+ ///
+ ///
+ ///
+ ///
+ public void TrackRawRetValMethodRewrite(
+ TypeSignature parameterType,
+ MethodDefinition method,
+ CilInstruction marker)
+ {
+ ThrowIfReadOnly();
+
+ _methodRewriteInfos.Add(new MethodRewriteInfo.RawRetVal
+ {
+ Type = parameterType,
+ Method = method,
+ Marker = marker
+ });
+ }
+
///
/// Tracks a method rewrite that involves loading a managed parameter in the specified method.
///
@@ -207,6 +228,27 @@ public void TrackNativeParameterMethodRewrite(
});
}
+ ///
+ /// Tracks a method rewrite that involves emitting calls to dispose (or release) a given value in the specified method.
+ ///
+ ///
+ ///
+ ///
+ public void TrackDisposeRewrite(
+ TypeSignature parameterType,
+ MethodDefinition method,
+ CilInstruction marker)
+ {
+ ThrowIfReadOnly();
+
+ _methodRewriteInfos.Add(new MethodRewriteInfo.Dispose
+ {
+ Type = parameterType,
+ Method = method,
+ Marker = marker
+ });
+ }
+
///
/// Enumerates all instances with info on two-pass code generation steps to perform.
///
diff --git a/src/WinRT.Interop.Generator/Models/MethodRewriteInfo/MethodRewriteInfo.Dispose.cs b/src/WinRT.Interop.Generator/Models/MethodRewriteInfo/MethodRewriteInfo.Dispose.cs
new file mode 100644
index 000000000..e3f8cbb25
--- /dev/null
+++ b/src/WinRT.Interop.Generator/Models/MethodRewriteInfo/MethodRewriteInfo.Dispose.cs
@@ -0,0 +1,24 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+namespace WindowsRuntime.InteropGenerator.Models;
+
+///
+internal partial class MethodRewriteInfo
+{
+ ///
+ /// Contains info for a target method for two-pass IL generation, to dispose (or release) a given value.
+ ///
+ ///
+ public sealed class Dispose : MethodRewriteInfo
+ {
+ ///
+ public override int CompareTo(MethodRewriteInfo? other)
+ {
+ // 'Dispose' objects have no additional state, so just compare with the base state
+ return ReferenceEquals(this, other)
+ ? 0
+ : CompareByMethodRewriteInfo(other);
+ }
+ }
+}
diff --git a/src/WinRT.Interop.Generator/Models/MethodRewriteInfo/MethodRewriteInfo.RawRetVal.cs b/src/WinRT.Interop.Generator/Models/MethodRewriteInfo/MethodRewriteInfo.RawRetVal.cs
new file mode 100644
index 000000000..730ce5362
--- /dev/null
+++ b/src/WinRT.Interop.Generator/Models/MethodRewriteInfo/MethodRewriteInfo.RawRetVal.cs
@@ -0,0 +1,24 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+namespace WindowsRuntime.InteropGenerator.Models;
+
+///
+internal partial class MethodRewriteInfo
+{
+ ///
+ /// Contains info for a target method for two-pass IL generation, for emitting direct calls to ConvertToUnmanaged.
+ ///
+ ///
+ public sealed class RawRetVal : MethodRewriteInfo
+ {
+ ///
+ public override int CompareTo(MethodRewriteInfo? other)
+ {
+ // 'RawRetVal' objects have no additional state, so just compare with the base state
+ return ReferenceEquals(this, other)
+ ? 0
+ : CompareByMethodRewriteInfo(other);
+ }
+ }
+}
diff --git a/src/WinRT.Interop.Generator/References/InteropReferences.cs b/src/WinRT.Interop.Generator/References/InteropReferences.cs
index 67b51c00d..0cd5ae3ad 100644
--- a/src/WinRT.Interop.Generator/References/InteropReferences.cs
+++ b/src/WinRT.Interop.Generator/References/InteropReferences.cs
@@ -903,6 +903,71 @@ public InteropReferences(
///
public TypeReference WindowsRuntimeArrayMarshaller => field ??= _windowsRuntimeModule.CreateTypeReference("WindowsRuntime.InteropServices.Marshalling"u8, "WindowsRuntimeArrayMarshaller"u8);
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.WindowsRuntimeBlittableValueTypeArrayMarshaller<T>.
+ ///
+ public TypeReference WindowsRuntimeBlittableValueTypeArrayMarshaller1 => field ??= _windowsRuntimeModule.CreateTypeReference("WindowsRuntime.InteropServices.Marshalling"u8, "WindowsRuntimeBlittableValueTypeArrayMarshaller`1"u8);
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.WindowsRuntimeManagedValueTypeArrayMarshaller<T, TAbi>.
+ ///
+ public TypeReference WindowsRuntimeManagedValueTypeArrayMarshaller2 => field ??= _windowsRuntimeModule.CreateTypeReference("WindowsRuntime.InteropServices.Marshalling"u8, "WindowsRuntimeManagedValueTypeArrayMarshaller`2"u8);
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.WindowsRuntimeUnmanagedValueTypeArrayMarshaller<T, TAbi>.
+ ///
+ public TypeReference WindowsRuntimeUnmanagedValueTypeArrayMarshaller2 => field ??= _windowsRuntimeModule.CreateTypeReference("WindowsRuntime.InteropServices.Marshalling"u8, "WindowsRuntimeUnmanagedValueTypeArrayMarshaller`2"u8);
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.WindowsRuntimeReferenceTypeArrayMarshaller<T>.
+ ///
+ public TypeReference WindowsRuntimeReferenceTypeArrayMarshaller1 => field ??= _windowsRuntimeModule.CreateTypeReference("WindowsRuntime.InteropServices.Marshalling"u8, "WindowsRuntimeReferenceTypeArrayMarshaller`1"u8);
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.WindowsRuntimeUnknownArrayMarshaller.
+ ///
+ public TypeReference WindowsRuntimeUnknownArrayMarshaller => field ??= _windowsRuntimeModule.CreateTypeReference("WindowsRuntime.InteropServices.Marshalling"u8, "WindowsRuntimeUnknownArrayMarshaller"u8);
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.WindowsRuntimeKeyValuePairTypeArrayMarshaller<TKey, TValue>.
+ ///
+ public TypeReference WindowsRuntimeKeyValuePairTypeArrayMarshaller2 => field ??= _windowsRuntimeModule.CreateTypeReference("WindowsRuntime.InteropServices.Marshalling"u8, "WindowsRuntimeKeyValuePairTypeArrayMarshaller`2"u8);
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.IWindowsRuntimeReferenceTypeArrayElementMarshaller<T>.
+ ///
+ public TypeReference IWindowsRuntimeReferenceTypeArrayElementMarshaller1 => field ??= _windowsRuntimeModule.CreateTypeReference("WindowsRuntime.InteropServices.Marshalling"u8, "IWindowsRuntimeReferenceTypeArrayElementMarshaller`1"u8);
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.IWindowsRuntimeManagedValueTypeArrayElementMarshaller<T, TAbi>.
+ ///
+ public TypeReference IWindowsRuntimeManagedValueTypeArrayElementMarshaller2 => field ??= _windowsRuntimeModule.CreateTypeReference("WindowsRuntime.InteropServices.Marshalling"u8, "IWindowsRuntimeManagedValueTypeArrayElementMarshaller`2"u8);
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.IWindowsRuntimeUnmanagedValueTypeArrayElementMarshaller<T, TAbi>.
+ ///
+ public TypeReference IWindowsRuntimeUnmanagedValueTypeArrayElementMarshaller2 => field ??= _windowsRuntimeModule.CreateTypeReference("WindowsRuntime.InteropServices.Marshalling"u8, "IWindowsRuntimeUnmanagedValueTypeArrayElementMarshaller`2"u8);
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.IWindowsRuntimeKeyValuePairTypeArrayElementMarshaller<TKey, TValue>.
+ ///
+ public TypeReference IWindowsRuntimeKeyValuePairTypeArrayElementMarshaller2 => field ??= _windowsRuntimeModule.CreateTypeReference("WindowsRuntime.InteropServices.Marshalling"u8, "IWindowsRuntimeKeyValuePairTypeArrayElementMarshaller`2"u8);
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.TypeArrayMarshaller.
+ ///
+ public TypeReference TypeArrayMarshaller => field ??= _windowsRuntimeModule.CreateTypeReference("WindowsRuntime.InteropServices.Marshalling"u8, "TypeArrayMarshaller"u8);
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.HStringArrayMarshaller.
+ ///
+ public TypeReference HStringArrayMarshaller => field ??= _windowsRuntimeModule.CreateTypeReference("WindowsRuntime.InteropServices.Marshalling"u8, "HStringArrayMarshaller"u8);
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.ExceptionArrayMarshaller.
+ ///
+ public TypeReference ExceptionArrayMarshaller => field ??= _windowsRuntimeModule.CreateTypeReference("WindowsRuntime.InteropServices.Marshalling"u8, "ExceptionArrayMarshaller"u8);
+
///
/// Gets the for WindowsRuntime.InteropServices.WindowsRuntimeValueTypeMarshaller.
///
@@ -928,11 +993,6 @@ public InteropReferences(
///
public TypeReference RestrictedErrorInfo => field ??= _windowsRuntimeModule.CreateTypeReference("WindowsRuntime.InteropServices"u8, "RestrictedErrorInfo"u8);
- ///
- /// Gets the for WindowsRuntime.InteropServices.WindowsRuntimeArrayHelpers.
- ///
- public TypeReference WindowsRuntimeArrayHelpers => field ??= _windowsRuntimeModule.CreateTypeReference("WindowsRuntime.InteropServices"u8, "WindowsRuntimeArrayHelpers"u8);
-
///
/// Gets the for WindowsRuntime.InteropServices.Marshalling.RestrictedErrorInfoExceptionMarshaller.
///
@@ -1836,6 +1896,175 @@ public InteropReferences(
_corLibTypeFactory.Void.MakePointerType(),
Guid.ToValueTypeSignature().MakeByReferenceType()]));
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.WindowsRuntimeUnknownArrayMarshaller.Free.
+ ///
+ public MemberReference WindowsRuntimeUnknownArrayMarshallerFree => field ??= WindowsRuntimeUnknownArrayMarshaller
+ .CreateMemberReference("Free"u8, MethodSignature.CreateStatic(
+ returnType: _corLibTypeFactory.Void,
+ parameterTypes: [
+ _corLibTypeFactory.UInt32,
+ _corLibTypeFactory.Void.MakePointerType().MakePointerType()]));
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.TypeArrayMarshaller.ConvertToUnmanaged.
+ ///
+ public MemberReference TypeArrayMarshallerConvertToUnmanaged => field ??= TypeArrayMarshaller
+ .CreateMemberReference("ConvertToUnmanaged"u8, MethodSignature.CreateStatic(
+ returnType: _corLibTypeFactory.Void,
+ parameterTypes: [
+ ReadOnlySpan1.MakeGenericValueType(Type.ToTypeSignature()),
+ _corLibTypeFactory.UInt32.MakeByReferenceType(),
+ AbiType.ToValueTypeSignature().MakePointerType().MakeByReferenceType()]));
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.TypeArrayMarshaller.ConvertToManaged.
+ ///
+ public MemberReference TypeArrayMarshallerConvertToManaged => field ??= TypeArrayMarshaller
+ .CreateMemberReference("ConvertToManaged"u8, MethodSignature.CreateStatic(
+ returnType: Type.ToReferenceTypeSignature().MakeSzArrayType(),
+ parameterTypes: [
+ _corLibTypeFactory.UInt32,
+ AbiType.ToValueTypeSignature().MakePointerType()]));
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.TypeArrayMarshaller.CopyToUnmanaged.
+ ///
+ public MemberReference TypeArrayMarshallerCopyToUnmanaged => field ??= TypeArrayMarshaller
+ .CreateMemberReference("CopyToUnmanaged"u8, MethodSignature.CreateStatic(
+ returnType: _corLibTypeFactory.Void,
+ parameterTypes: [
+ ReadOnlySpan1.MakeGenericValueType(Type.ToTypeSignature()),
+ _corLibTypeFactory.UInt32,
+ AbiType.ToValueTypeSignature().MakePointerType()]));
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.TypeArrayMarshaller.CopyToManaged.
+ ///
+ public MemberReference TypeArrayMarshallerCopyToManaged => field ??= TypeArrayMarshaller
+ .CreateMemberReference("CopyToManaged"u8, MethodSignature.CreateStatic(
+ returnType: _corLibTypeFactory.Void,
+ parameterTypes: [
+ _corLibTypeFactory.UInt32,
+ AbiType.ToValueTypeSignature().MakePointerType(),
+ Span1.MakeGenericValueType(Type.ToTypeSignature())]));
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.TypeArrayMarshaller.Free.
+ ///
+ public MemberReference TypeArrayMarshallerFree => field ??= TypeArrayMarshaller
+ .CreateMemberReference("Free"u8, MethodSignature.CreateStatic(
+ returnType: _corLibTypeFactory.Void,
+ parameterTypes: [
+ _corLibTypeFactory.UInt32,
+ AbiType.ToValueTypeSignature().MakePointerType()]));
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.HStringArrayMarshaller.ConvertToUnmanaged.
+ ///
+ public MemberReference HStringArrayMarshallerConvertToUnmanaged => field ??= HStringArrayMarshaller
+ .CreateMemberReference("ConvertToUnmanaged"u8, MethodSignature.CreateStatic(
+ returnType: _corLibTypeFactory.Void,
+ parameterTypes: [
+ ReadOnlySpan1.MakeGenericValueType(_corLibTypeFactory.String),
+ _corLibTypeFactory.UInt32.MakeByReferenceType(),
+ _corLibTypeFactory.Void.MakePointerType().MakePointerType().MakeByReferenceType()]));
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.HStringArrayMarshaller.ConvertToManaged.
+ ///
+ public MemberReference HStringArrayMarshallerConvertToManaged => field ??= HStringArrayMarshaller
+ .CreateMemberReference("ConvertToManaged"u8, MethodSignature.CreateStatic(
+ returnType: _corLibTypeFactory.String.MakeSzArrayType(),
+ parameterTypes: [
+ _corLibTypeFactory.UInt32,
+ _corLibTypeFactory.Void.MakePointerType().MakePointerType()]));
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.HStringArrayMarshaller.CopyToUnmanaged.
+ ///
+ public MemberReference HStringArrayMarshallerCopyToUnmanaged => field ??= HStringArrayMarshaller
+ .CreateMemberReference("CopyToUnmanaged"u8, MethodSignature.CreateStatic(
+ returnType: _corLibTypeFactory.Void,
+ parameterTypes: [
+ ReadOnlySpan1.MakeGenericValueType(_corLibTypeFactory.String),
+ _corLibTypeFactory.UInt32,
+ _corLibTypeFactory.Void.MakePointerType().MakePointerType()]));
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.HStringArrayMarshaller.CopyToManaged.
+ ///
+ public MemberReference HStringArrayMarshallerCopyToManaged => field ??= HStringArrayMarshaller
+ .CreateMemberReference("CopyToManaged"u8, MethodSignature.CreateStatic(
+ returnType: _corLibTypeFactory.Void,
+ parameterTypes: [
+ _corLibTypeFactory.UInt32,
+ _corLibTypeFactory.Void.MakePointerType().MakePointerType(),
+ Span1.MakeGenericValueType(_corLibTypeFactory.String)]));
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.HStringArrayMarshaller.Free.
+ ///
+ public MemberReference HStringArrayMarshallerFree => field ??= HStringArrayMarshaller
+ .CreateMemberReference("Free"u8, MethodSignature.CreateStatic(
+ returnType: _corLibTypeFactory.Void,
+ parameterTypes: [
+ _corLibTypeFactory.UInt32,
+ _corLibTypeFactory.Void.MakePointerType().MakePointerType()]));
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.ExceptionArrayMarshaller.ConvertToUnmanaged.
+ ///
+ public MemberReference ExceptionArrayMarshallerConvertToUnmanaged => field ??= ExceptionArrayMarshaller
+ .CreateMemberReference("ConvertToUnmanaged"u8, MethodSignature.CreateStatic(
+ returnType: _corLibTypeFactory.Void,
+ parameterTypes: [
+ ReadOnlySpan1.MakeGenericValueType(Exception.ToReferenceTypeSignature()),
+ _corLibTypeFactory.UInt32.MakeByReferenceType(),
+ AbiException.ToValueTypeSignature().MakePointerType().MakeByReferenceType()]));
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.ExceptionArrayMarshaller.ConvertToManaged.
+ ///
+ public MemberReference ExceptionArrayMarshallerConvertToManaged => field ??= ExceptionArrayMarshaller
+ .CreateMemberReference("ConvertToManaged"u8, MethodSignature.CreateStatic(
+ returnType: Exception.ToReferenceTypeSignature().MakeSzArrayType(),
+ parameterTypes: [
+ _corLibTypeFactory.UInt32,
+ AbiException.ToValueTypeSignature().MakePointerType()]));
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.ExceptionArrayMarshaller.CopyToUnmanaged.
+ ///
+ public MemberReference ExceptionArrayMarshallerCopyToUnmanaged => field ??= ExceptionArrayMarshaller
+ .CreateMemberReference("CopyToUnmanaged"u8, MethodSignature.CreateStatic(
+ returnType: _corLibTypeFactory.Void,
+ parameterTypes: [
+ ReadOnlySpan1.MakeGenericValueType(Exception.ToReferenceTypeSignature()),
+ _corLibTypeFactory.UInt32,
+ AbiException.ToValueTypeSignature().MakePointerType()]));
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.ExceptionArrayMarshaller.CopyToManaged.
+ ///
+ public MemberReference ExceptionArrayMarshallerCopyToManaged => field ??= ExceptionArrayMarshaller
+ .CreateMemberReference("CopyToManaged"u8, MethodSignature.CreateStatic(
+ returnType: _corLibTypeFactory.Void,
+ parameterTypes: [
+ _corLibTypeFactory.UInt32,
+ AbiException.ToValueTypeSignature().MakePointerType(),
+ Span1.MakeGenericValueType(Exception.ToReferenceTypeSignature())]));
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.ExceptionArrayMarshaller.Free.
+ ///
+ public MemberReference ExceptionArrayMarshallerFree => field ??= ExceptionArrayMarshaller
+ .CreateMemberReference("Free"u8, MethodSignature.CreateStatic(
+ returnType: _corLibTypeFactory.Void,
+ parameterTypes: [
+ _corLibTypeFactory.UInt32,
+ AbiException.ToValueTypeSignature().MakePointerType()]));
+
///
/// Gets the for WindowsRuntime.InteropServices.WindowsRuntimeValueTypeMarshaller.ConvertToUnmanagedUnsafe.
///
@@ -1920,52 +2149,609 @@ public InteropReferences(
parameterTypes: [_corLibTypeFactory.Int32]));
///
- /// Gets the for WindowsRuntime.InteropServices.WindowsRuntimeArrayHelpers.FreeHStringArrayUnsafe.
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.RestrictedErrorInfoExceptionMarshaller.ConvertToUnmanaged(Exception).
///
- public MemberReference WindowsRuntimeArrayHelpersFreeHStringArrayUnsafe => field ??= WindowsRuntimeArrayHelpers
- .CreateMemberReference("FreeHStringArrayUnsafe"u8, MethodSignature.CreateStatic(
- returnType: _corLibTypeFactory.Void,
- parameterTypes: [
- _corLibTypeFactory.UInt32,
- _corLibTypeFactory.Void.MakePointerType().MakePointerType()]));
+ public MemberReference RestrictedErrorInfoExceptionMarshallerConvertToUnmanaged => field ??= RestrictedErrorInfoExceptionMarshaller
+ .CreateMemberReference("ConvertToUnmanaged"u8, MethodSignature.CreateStatic(
+ returnType: _corLibTypeFactory.Int32,
+ parameterTypes: [new TypeReference(_corLibTypeFactory.CorLibScope, "System"u8, "Exception"u8).ToReferenceTypeSignature()]));
///
- /// Gets the for WindowsRuntime.InteropServices.WindowsRuntimeArrayHelpers.FreeObjectArrayUnsafe.
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.IWindowsRuntimeReferenceTypeArrayElementMarshaller<T>.ConvertToUnmanaged.
///
- public MemberReference WindowsRuntimeArrayHelpersFreeObjectArrayUnsafe => field ??= WindowsRuntimeArrayHelpers
- .CreateMemberReference("FreeObjectArrayUnsafe"u8, MethodSignature.CreateStatic(
- returnType: _corLibTypeFactory.Void,
- parameterTypes: [
- _corLibTypeFactory.UInt32,
- _corLibTypeFactory.Void.MakePointerType().MakePointerType()]));
+ /// The input element type.
+ public MemberReference IWindowsRuntimeReferenceTypeArrayElementMarshallerConvertToUnmanaged(TypeSignature elementType)
+ {
+ return IWindowsRuntimeReferenceTypeArrayElementMarshaller1
+ .MakeGenericReferenceType(elementType)
+ .ToTypeDefOrRef()
+ .CreateMemberReference("ConvertToUnmanaged"u8, MethodSignature.CreateStatic(
+ returnType: WindowsRuntimeObjectReferenceValue.ToValueTypeSignature(),
+ parameterTypes: [new GenericParameterSignature(GenericParameterType.Type, 0)]));
+ }
///
- /// Gets the for WindowsRuntime.InteropServices.WindowsRuntimeArrayHelpers.FreeTypeArrayUnsafe.
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.IWindowsRuntimeReferenceTypeArrayElementMarshaller<T>.ConvertToManaged.
///
- public MemberReference WindowsRuntimeArrayHelpersFreeTypeArrayUnsafe => field ??= WindowsRuntimeArrayHelpers
- .CreateMemberReference("FreeTypeArrayUnsafe"u8, MethodSignature.CreateStatic(
- returnType: _corLibTypeFactory.Void,
- parameterTypes: [
- _corLibTypeFactory.UInt32,
- AbiType.ToValueTypeSignature().MakePointerType()]));
+ /// The input element type.
+ public MemberReference IWindowsRuntimeReferenceTypeArrayElementMarshallerConvertToManaged(TypeSignature elementType)
+ {
+ return IWindowsRuntimeReferenceTypeArrayElementMarshaller1
+ .MakeGenericReferenceType(elementType)
+ .ToTypeDefOrRef()
+ .CreateMemberReference("ConvertToManaged"u8, MethodSignature.CreateStatic(
+ returnType: new GenericParameterSignature(GenericParameterType.Type, 0),
+ parameterTypes: [_corLibTypeFactory.Void.MakePointerType()]));
+ }
///
- /// Gets the for WindowsRuntime.InteropServices.WindowsRuntimeArrayHelpers.FreeBlittableArrayUnsafe.
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.IWindowsRuntimeManagedValueTypeArrayElementMarshaller<T, TAbi>.ConvertToUnmanaged.
///
- public MemberReference WindowsRuntimeArrayHelpersFreeBlittableArrayUnsafe => field ??= WindowsRuntimeArrayHelpers
- .CreateMemberReference("FreeBlittableArrayUnsafe"u8, MethodSignature.CreateStatic(
- returnType: _corLibTypeFactory.Void,
- parameterTypes: [
- _corLibTypeFactory.UInt32,
- _corLibTypeFactory.Void.MakePointerType()]));
+ /// The input element type.
+ /// The ABI type.
+ public MemberReference IWindowsRuntimeManagedValueTypeArrayElementMarshallerConvertToUnmanaged(TypeSignature elementType, TypeSignature abiType)
+ {
+ return IWindowsRuntimeManagedValueTypeArrayElementMarshaller2
+ .MakeGenericReferenceType(elementType, abiType)
+ .ToTypeDefOrRef()
+ .CreateMemberReference("ConvertToUnmanaged"u8, MethodSignature.CreateStatic(
+ returnType: new GenericParameterSignature(GenericParameterType.Type, 1),
+ parameterTypes: [new GenericParameterSignature(GenericParameterType.Type, 0)]));
+ }
///
- /// Gets the for WindowsRuntime.InteropServices.Marshalling.RestrictedErrorInfoExceptionMarshaller.ConvertToUnmanaged(Exception).
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.IWindowsRuntimeManagedValueTypeArrayElementMarshaller<T, TAbi>.ConvertToManaged.
///
- public MemberReference RestrictedErrorInfoExceptionMarshallerConvertToUnmanaged => field ??= RestrictedErrorInfoExceptionMarshaller
- .CreateMemberReference("ConvertToUnmanaged"u8, MethodSignature.CreateStatic(
- returnType: _corLibTypeFactory.Int32,
- parameterTypes: [new TypeReference(_corLibTypeFactory.CorLibScope, "System"u8, "Exception"u8).ToReferenceTypeSignature()]));
+ /// The input element type.
+ /// The ABI type.
+ public MemberReference IWindowsRuntimeManagedValueTypeArrayElementMarshallerConvertToManaged(TypeSignature elementType, TypeSignature abiType)
+ {
+ return IWindowsRuntimeManagedValueTypeArrayElementMarshaller2
+ .MakeGenericReferenceType(elementType, abiType)
+ .ToTypeDefOrRef()
+ .CreateMemberReference("ConvertToManaged"u8, MethodSignature.CreateStatic(
+ returnType: new GenericParameterSignature(GenericParameterType.Type, 0),
+ parameterTypes: [new GenericParameterSignature(GenericParameterType.Type, 1)]));
+ }
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.IWindowsRuntimeManagedValueTypeArrayElementMarshaller<T, TAbi>.Dispose.
+ ///
+ /// The input element type.
+ /// The ABI type.
+ public MemberReference IWindowsRuntimeManagedValueTypeArrayElementMarshallerDispose(TypeSignature elementType, TypeSignature abiType)
+ {
+ return IWindowsRuntimeManagedValueTypeArrayElementMarshaller2
+ .MakeGenericReferenceType(elementType, abiType)
+ .ToTypeDefOrRef()
+ .CreateMemberReference("Dispose"u8, MethodSignature.CreateStatic(
+ returnType: _corLibTypeFactory.Void,
+ parameterTypes: [new GenericParameterSignature(GenericParameterType.Type, 1)]));
+ }
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.IWindowsRuntimeUnmanagedValueTypeArrayElementMarshaller<T, TAbi>.ConvertToUnmanaged.
+ ///
+ /// The input element type.
+ /// The ABI type.
+ public MemberReference IWindowsRuntimeUnmanagedValueTypeArrayElementMarshallerConvertToUnmanaged(TypeSignature elementType, TypeSignature abiType)
+ {
+ return IWindowsRuntimeUnmanagedValueTypeArrayElementMarshaller2
+ .MakeGenericReferenceType(elementType, abiType)
+ .ToTypeDefOrRef()
+ .CreateMemberReference("ConvertToUnmanaged"u8, MethodSignature.CreateStatic(
+ returnType: new GenericParameterSignature(GenericParameterType.Type, 1),
+ parameterTypes: [new GenericParameterSignature(GenericParameterType.Type, 0)]));
+ }
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.IWindowsRuntimeUnmanagedValueTypeArrayElementMarshaller<T, TAbi>.ConvertToManaged.
+ ///
+ /// The input element type.
+ /// The ABI type.
+ public MemberReference IWindowsRuntimeUnmanagedValueTypeArrayElementMarshallerConvertToManaged(TypeSignature elementType, TypeSignature abiType)
+ {
+ return IWindowsRuntimeUnmanagedValueTypeArrayElementMarshaller2
+ .MakeGenericReferenceType(elementType, abiType)
+ .ToTypeDefOrRef()
+ .CreateMemberReference("ConvertToManaged"u8, MethodSignature.CreateStatic(
+ returnType: new GenericParameterSignature(GenericParameterType.Type, 0),
+ parameterTypes: [new GenericParameterSignature(GenericParameterType.Type, 1)]));
+ }
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.IWindowsRuntimeKeyValuePairTypeArrayElementMarshaller<TKey, TValue>.ConvertToUnmanaged.
+ ///
+ /// The input key type.
+ /// The input value type.
+ public MemberReference IWindowsRuntimeKeyValuePairTypeArrayElementMarshallerConvertToUnmanaged(TypeSignature keyType, TypeSignature valueType)
+ {
+ return IWindowsRuntimeKeyValuePairTypeArrayElementMarshaller2
+ .MakeGenericReferenceType(keyType, valueType)
+ .ToTypeDefOrRef()
+ .CreateMemberReference("ConvertToUnmanaged"u8, MethodSignature.CreateStatic(
+ returnType: WindowsRuntimeObjectReferenceValue.ToValueTypeSignature(),
+ parameterTypes: [
+ KeyValuePair2.MakeGenericValueType(
+ new GenericParameterSignature(GenericParameterType.Type, 0),
+ new GenericParameterSignature(GenericParameterType.Type, 1))]));
+ }
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.IWindowsRuntimeKeyValuePairTypeArrayElementMarshaller<TKey, TValue>.ConvertToManaged.
+ ///
+ /// The input key type.
+ /// The input value type.
+ public MemberReference IWindowsRuntimeKeyValuePairTypeArrayElementMarshallerConvertToManaged(TypeSignature keyType, TypeSignature valueType)
+ {
+ return IWindowsRuntimeKeyValuePairTypeArrayElementMarshaller2
+ .MakeGenericReferenceType(keyType, valueType)
+ .ToTypeDefOrRef()
+ .CreateMemberReference("ConvertToManaged"u8, MethodSignature.CreateStatic(
+ returnType: KeyValuePair2.MakeGenericValueType(
+ new GenericParameterSignature(GenericParameterType.Type, 0),
+ new GenericParameterSignature(GenericParameterType.Type, 1)),
+ parameterTypes: [_corLibTypeFactory.Void.MakePointerType()]));
+ }
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.WindowsRuntimeBlittableValueTypeArrayMarshaller<T>.ConvertToUnmanaged.
+ ///
+ /// The input element type.
+ public MemberReference WindowsRuntimeBlittableValueTypeArrayMarshallerConvertToUnmanaged(TypeSignature elementType)
+ {
+ return WindowsRuntimeBlittableValueTypeArrayMarshaller1
+ .MakeGenericReferenceType(elementType)
+ .ToTypeDefOrRef()
+ .CreateMemberReference("ConvertToUnmanaged"u8, MethodSignature.CreateStatic(
+ returnType: _corLibTypeFactory.Void,
+ parameterTypes: [
+ ReadOnlySpan1.MakeGenericValueType(new GenericParameterSignature(GenericParameterType.Type, 0)),
+ _corLibTypeFactory.UInt32.MakeByReferenceType(),
+ new GenericParameterSignature(GenericParameterType.Type, 0).MakePointerType().MakeByReferenceType()]));
+ }
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.WindowsRuntimeBlittableValueTypeArrayMarshaller<T>.ConvertToManaged.
+ ///
+ /// The input element type.
+ public MemberReference WindowsRuntimeBlittableValueTypeArrayMarshallerConvertToManaged(TypeSignature elementType)
+ {
+ return WindowsRuntimeBlittableValueTypeArrayMarshaller1
+ .MakeGenericReferenceType(elementType)
+ .ToTypeDefOrRef()
+ .CreateMemberReference("ConvertToManaged"u8, MethodSignature.CreateStatic(
+ returnType: new GenericParameterSignature(GenericParameterType.Type, 0).MakeSzArrayType(),
+ parameterTypes: [
+ _corLibTypeFactory.UInt32,
+ new GenericParameterSignature(GenericParameterType.Type, 0).MakePointerType()]));
+ }
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.WindowsRuntimeBlittableValueTypeArrayMarshaller<T>.CopyToUnmanaged.
+ ///
+ /// The input element type.
+ public MemberReference WindowsRuntimeBlittableValueTypeArrayMarshallerCopyToUnmanaged(TypeSignature elementType)
+ {
+ return WindowsRuntimeBlittableValueTypeArrayMarshaller1
+ .MakeGenericReferenceType(elementType)
+ .ToTypeDefOrRef()
+ .CreateMemberReference("CopyToUnmanaged"u8, MethodSignature.CreateStatic(
+ returnType: _corLibTypeFactory.Void,
+ parameterTypes: [
+ ReadOnlySpan1.MakeGenericValueType(new GenericParameterSignature(GenericParameterType.Type, 0)),
+ _corLibTypeFactory.UInt32,
+ new GenericParameterSignature(GenericParameterType.Type, 0).MakePointerType()]));
+ }
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.WindowsRuntimeBlittableValueTypeArrayMarshaller<T>.CopyToManaged.
+ ///
+ /// The input element type.
+ public MemberReference WindowsRuntimeBlittableValueTypeArrayMarshallerCopyToManaged(TypeSignature elementType)
+ {
+ return WindowsRuntimeBlittableValueTypeArrayMarshaller1
+ .MakeGenericReferenceType(elementType)
+ .ToTypeDefOrRef()
+ .CreateMemberReference("CopyToManaged"u8, MethodSignature.CreateStatic(
+ returnType: _corLibTypeFactory.Void,
+ parameterTypes: [
+ _corLibTypeFactory.UInt32,
+ new GenericParameterSignature(GenericParameterType.Type, 0).MakePointerType(),
+ Span1.MakeGenericValueType(new GenericParameterSignature(GenericParameterType.Type, 0))]));
+ }
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.WindowsRuntimeBlittableValueTypeArrayMarshaller<T>.Free.
+ ///
+ /// The input element type.
+ public MemberReference WindowsRuntimeBlittableValueTypeArrayMarshallerFree(TypeSignature elementType)
+ {
+ return WindowsRuntimeBlittableValueTypeArrayMarshaller1
+ .MakeGenericReferenceType(elementType)
+ .ToTypeDefOrRef()
+ .CreateMemberReference("Free"u8, MethodSignature.CreateStatic(
+ returnType: _corLibTypeFactory.Void,
+ parameterTypes: [
+ _corLibTypeFactory.UInt32,
+ new GenericParameterSignature(GenericParameterType.Type, 0).MakePointerType()]));
+ }
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.WindowsRuntimeManagedValueTypeArrayMarshaller<T, TAbi>.ConvertToUnmanaged<TElementMarshaller>.
+ ///
+ /// The input element type.
+ /// The ABI type.
+ /// The element marshaller type.
+ public MethodSpecification WindowsRuntimeManagedValueTypeArrayMarshallerConvertToUnmanaged(TypeSignature elementType, TypeSignature abiType, TypeSignature elementMarshallerType)
+ {
+ return WindowsRuntimeManagedValueTypeArrayMarshaller2
+ .MakeGenericReferenceType(elementType, abiType)
+ .ToTypeDefOrRef()
+ .CreateMemberReference("ConvertToUnmanaged"u8, MethodSignature.CreateStatic(
+ returnType: _corLibTypeFactory.Void,
+ genericParameterCount: 1,
+ parameterTypes: [
+ ReadOnlySpan1.MakeGenericValueType(new GenericParameterSignature(GenericParameterType.Type, 0)),
+ _corLibTypeFactory.UInt32.MakeByReferenceType(),
+ new GenericParameterSignature(GenericParameterType.Type, 1).MakePointerType().MakeByReferenceType()]))
+ .MakeGenericInstanceMethod(elementMarshallerType);
+ }
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.WindowsRuntimeManagedValueTypeArrayMarshaller<T, TAbi>.ConvertToManaged<TElementMarshaller>.
+ ///
+ /// The input element type.
+ /// The ABI type.
+ /// The element marshaller type.
+ public MethodSpecification WindowsRuntimeManagedValueTypeArrayMarshallerConvertToManaged(TypeSignature elementType, TypeSignature abiType, TypeSignature elementMarshallerType)
+ {
+ return WindowsRuntimeManagedValueTypeArrayMarshaller2
+ .MakeGenericReferenceType(elementType, abiType)
+ .ToTypeDefOrRef()
+ .CreateMemberReference("ConvertToManaged"u8, MethodSignature.CreateStatic(
+ returnType: new GenericParameterSignature(GenericParameterType.Type, 0).MakeSzArrayType(),
+ genericParameterCount: 1,
+ parameterTypes: [
+ _corLibTypeFactory.UInt32,
+ new GenericParameterSignature(GenericParameterType.Type, 1).MakePointerType()]))
+ .MakeGenericInstanceMethod(elementMarshallerType);
+ }
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.WindowsRuntimeManagedValueTypeArrayMarshaller<T, TAbi>.CopyToUnmanaged<TElementMarshaller>.
+ ///
+ /// The input element type.
+ /// The ABI type.
+ /// The element marshaller type.
+ public MethodSpecification WindowsRuntimeManagedValueTypeArrayMarshallerCopyToUnmanaged(TypeSignature elementType, TypeSignature abiType, TypeSignature elementMarshallerType)
+ {
+ return WindowsRuntimeManagedValueTypeArrayMarshaller2
+ .MakeGenericReferenceType(elementType, abiType)
+ .ToTypeDefOrRef()
+ .CreateMemberReference("CopyToUnmanaged"u8, MethodSignature.CreateStatic(
+ returnType: _corLibTypeFactory.Void,
+ genericParameterCount: 1,
+ parameterTypes: [
+ ReadOnlySpan1.MakeGenericValueType(new GenericParameterSignature(GenericParameterType.Type, 0)),
+ _corLibTypeFactory.UInt32,
+ new GenericParameterSignature(GenericParameterType.Type, 1).MakePointerType()]))
+ .MakeGenericInstanceMethod(elementMarshallerType);
+ }
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.WindowsRuntimeManagedValueTypeArrayMarshaller<T, TAbi>.CopyToManaged<TElementMarshaller>.
+ ///
+ /// The input element type.
+ /// The ABI type.
+ /// The element marshaller type.
+ public MethodSpecification WindowsRuntimeManagedValueTypeArrayMarshallerCopyToManaged(TypeSignature elementType, TypeSignature abiType, TypeSignature elementMarshallerType)
+ {
+ return WindowsRuntimeManagedValueTypeArrayMarshaller2
+ .MakeGenericReferenceType(elementType, abiType)
+ .ToTypeDefOrRef()
+ .CreateMemberReference("CopyToManaged"u8, MethodSignature.CreateStatic(
+ returnType: _corLibTypeFactory.Void,
+ genericParameterCount: 1,
+ parameterTypes: [
+ _corLibTypeFactory.UInt32,
+ new GenericParameterSignature(GenericParameterType.Type, 1).MakePointerType(),
+ Span1.MakeGenericValueType(new GenericParameterSignature(GenericParameterType.Type, 0))]))
+ .MakeGenericInstanceMethod(elementMarshallerType);
+ }
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.WindowsRuntimeManagedValueTypeArrayMarshaller<T, TAbi>.Free<TElementMarshaller>.
+ ///
+ /// The input element type.
+ /// The ABI type.
+ /// The element marshaller type.
+ public MethodSpecification WindowsRuntimeManagedValueTypeArrayMarshallerFree(TypeSignature elementType, TypeSignature abiType, TypeSignature elementMarshallerType)
+ {
+ return WindowsRuntimeManagedValueTypeArrayMarshaller2
+ .MakeGenericReferenceType(elementType, abiType)
+ .ToTypeDefOrRef()
+ .CreateMemberReference("Free"u8, MethodSignature.CreateStatic(
+ returnType: _corLibTypeFactory.Void,
+ genericParameterCount: 1,
+ parameterTypes: [
+ _corLibTypeFactory.UInt32,
+ new GenericParameterSignature(GenericParameterType.Type, 1).MakePointerType()]))
+ .MakeGenericInstanceMethod(elementMarshallerType);
+ }
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.WindowsRuntimeUnmanagedValueTypeArrayMarshaller<T, TAbi>.ConvertToUnmanaged<TElementMarshaller>.
+ ///
+ /// The input element type.
+ /// The ABI type.
+ /// The element marshaller type.
+ public MethodSpecification WindowsRuntimeUnmanagedValueTypeArrayMarshallerConvertToUnmanaged(TypeSignature elementType, TypeSignature abiType, TypeSignature elementMarshallerType)
+ {
+ return WindowsRuntimeUnmanagedValueTypeArrayMarshaller2
+ .MakeGenericReferenceType(elementType, abiType)
+ .ToTypeDefOrRef()
+ .CreateMemberReference("ConvertToUnmanaged"u8, MethodSignature.CreateStatic(
+ returnType: _corLibTypeFactory.Void,
+ genericParameterCount: 1,
+ parameterTypes: [
+ ReadOnlySpan1.MakeGenericValueType(new GenericParameterSignature(GenericParameterType.Type, 0)),
+ _corLibTypeFactory.UInt32.MakeByReferenceType(),
+ new GenericParameterSignature(GenericParameterType.Type, 1).MakePointerType().MakeByReferenceType()]))
+ .MakeGenericInstanceMethod(elementMarshallerType);
+ }
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.WindowsRuntimeUnmanagedValueTypeArrayMarshaller<T, TAbi>.ConvertToManaged<TElementMarshaller>.
+ ///
+ /// The input element type.
+ /// The ABI type.
+ /// The element marshaller type.
+ public MethodSpecification WindowsRuntimeUnmanagedValueTypeArrayMarshallerConvertToManaged(TypeSignature elementType, TypeSignature abiType, TypeSignature elementMarshallerType)
+ {
+ return WindowsRuntimeUnmanagedValueTypeArrayMarshaller2
+ .MakeGenericReferenceType(elementType, abiType)
+ .ToTypeDefOrRef()
+ .CreateMemberReference("ConvertToManaged"u8, MethodSignature.CreateStatic(
+ returnType: new GenericParameterSignature(GenericParameterType.Type, 0).MakeSzArrayType(),
+ genericParameterCount: 1,
+ parameterTypes: [
+ _corLibTypeFactory.UInt32,
+ new GenericParameterSignature(GenericParameterType.Type, 1).MakePointerType()]))
+ .MakeGenericInstanceMethod(elementMarshallerType);
+ }
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.WindowsRuntimeUnmanagedValueTypeArrayMarshaller<T, TAbi>.CopyToUnmanaged<TElementMarshaller>.
+ ///
+ /// The input element type.
+ /// The ABI type.
+ /// The element marshaller type.
+ public MethodSpecification WindowsRuntimeUnmanagedValueTypeArrayMarshallerCopyToUnmanaged(TypeSignature elementType, TypeSignature abiType, TypeSignature elementMarshallerType)
+ {
+ return WindowsRuntimeUnmanagedValueTypeArrayMarshaller2
+ .MakeGenericReferenceType(elementType, abiType)
+ .ToTypeDefOrRef()
+ .CreateMemberReference("CopyToUnmanaged"u8, MethodSignature.CreateStatic(
+ returnType: _corLibTypeFactory.Void,
+ genericParameterCount: 1,
+ parameterTypes: [
+ ReadOnlySpan1.MakeGenericValueType(new GenericParameterSignature(GenericParameterType.Type, 0)),
+ _corLibTypeFactory.UInt32,
+ new GenericParameterSignature(GenericParameterType.Type, 1).MakePointerType()]))
+ .MakeGenericInstanceMethod(elementMarshallerType);
+ }
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.WindowsRuntimeUnmanagedValueTypeArrayMarshaller<T, TAbi>.CopyToManaged<TElementMarshaller>.
+ ///
+ /// The input element type.
+ /// The ABI type.
+ /// The element marshaller type.
+ public MethodSpecification WindowsRuntimeUnmanagedValueTypeArrayMarshallerCopyToManaged(TypeSignature elementType, TypeSignature abiType, TypeSignature elementMarshallerType)
+ {
+ return WindowsRuntimeUnmanagedValueTypeArrayMarshaller2
+ .MakeGenericReferenceType(elementType, abiType)
+ .ToTypeDefOrRef()
+ .CreateMemberReference("CopyToManaged"u8, MethodSignature.CreateStatic(
+ returnType: _corLibTypeFactory.Void,
+ genericParameterCount: 1,
+ parameterTypes: [
+ _corLibTypeFactory.UInt32,
+ new GenericParameterSignature(GenericParameterType.Type, 1).MakePointerType(),
+ Span1.MakeGenericValueType(new GenericParameterSignature(GenericParameterType.Type, 0))]))
+ .MakeGenericInstanceMethod(elementMarshallerType);
+ }
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.WindowsRuntimeUnmanagedValueTypeArrayMarshaller<T, TAbi>.Free.
+ ///
+ /// The input element type.
+ /// The ABI type.
+ public MemberReference WindowsRuntimeUnmanagedValueTypeArrayMarshallerFree(TypeSignature elementType, TypeSignature abiType)
+ {
+ return WindowsRuntimeUnmanagedValueTypeArrayMarshaller2
+ .MakeGenericReferenceType(elementType, abiType)
+ .ToTypeDefOrRef()
+ .CreateMemberReference("Free"u8, MethodSignature.CreateStatic(
+ returnType: _corLibTypeFactory.Void,
+ parameterTypes: [
+ _corLibTypeFactory.UInt32,
+ new GenericParameterSignature(GenericParameterType.Type, 1).MakePointerType()]));
+ }
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.WindowsRuntimeReferenceTypeArrayMarshaller<T>.ConvertToUnmanaged<TElementMarshaller>.
+ ///
+ /// The input element type.
+ /// The element marshaller type.
+ public MethodSpecification WindowsRuntimeReferenceTypeArrayMarshallerConvertToUnmanaged(TypeSignature elementType, TypeSignature elementMarshallerType)
+ {
+ return WindowsRuntimeReferenceTypeArrayMarshaller1
+ .MakeGenericReferenceType(elementType)
+ .ToTypeDefOrRef()
+ .CreateMemberReference("ConvertToUnmanaged"u8, MethodSignature.CreateStatic(
+ returnType: _corLibTypeFactory.Void,
+ genericParameterCount: 1,
+ parameterTypes: [
+ ReadOnlySpan1.MakeGenericValueType(new GenericParameterSignature(GenericParameterType.Type, 0)),
+ _corLibTypeFactory.UInt32.MakeByReferenceType(),
+ _corLibTypeFactory.Void.MakePointerType().MakePointerType().MakeByReferenceType()]))
+ .MakeGenericInstanceMethod(elementMarshallerType);
+ }
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.WindowsRuntimeReferenceTypeArrayMarshaller<T>.ConvertToManaged<TElementMarshaller>.
+ ///
+ /// The input element type.
+ /// The element marshaller type.
+ public MethodSpecification WindowsRuntimeReferenceTypeArrayMarshallerConvertToManaged(TypeSignature elementType, TypeSignature elementMarshallerType)
+ {
+ return WindowsRuntimeReferenceTypeArrayMarshaller1
+ .MakeGenericReferenceType(elementType)
+ .ToTypeDefOrRef()
+ .CreateMemberReference("ConvertToManaged"u8, MethodSignature.CreateStatic(
+ returnType: new GenericParameterSignature(GenericParameterType.Type, 0).MakeSzArrayType(),
+ genericParameterCount: 1,
+ parameterTypes: [
+ _corLibTypeFactory.UInt32,
+ _corLibTypeFactory.Void.MakePointerType().MakePointerType()]))
+ .MakeGenericInstanceMethod(elementMarshallerType);
+ }
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.WindowsRuntimeReferenceTypeArrayMarshaller<T>.CopyToUnmanaged<TElementMarshaller>.
+ ///
+ /// The input element type.
+ /// The element marshaller type.
+ public MethodSpecification WindowsRuntimeReferenceTypeArrayMarshallerCopyToUnmanaged(TypeSignature elementType, TypeSignature elementMarshallerType)
+ {
+ return WindowsRuntimeReferenceTypeArrayMarshaller1
+ .MakeGenericReferenceType(elementType)
+ .ToTypeDefOrRef()
+ .CreateMemberReference("CopyToUnmanaged"u8, MethodSignature.CreateStatic(
+ returnType: _corLibTypeFactory.Void,
+ genericParameterCount: 1,
+ parameterTypes: [
+ ReadOnlySpan1.MakeGenericValueType(new GenericParameterSignature(GenericParameterType.Type, 0)),
+ _corLibTypeFactory.UInt32,
+ _corLibTypeFactory.Void.MakePointerType().MakePointerType()]))
+ .MakeGenericInstanceMethod(elementMarshallerType);
+ }
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.WindowsRuntimeReferenceTypeArrayMarshaller<T>.CopyToManaged<TElementMarshaller>.
+ ///
+ /// The input element type.
+ /// The element marshaller type.
+ public MethodSpecification WindowsRuntimeReferenceTypeArrayMarshallerCopyToManaged(TypeSignature elementType, TypeSignature elementMarshallerType)
+ {
+ return WindowsRuntimeReferenceTypeArrayMarshaller1
+ .MakeGenericReferenceType(elementType)
+ .ToTypeDefOrRef()
+ .CreateMemberReference("CopyToManaged"u8, MethodSignature.CreateStatic(
+ returnType: _corLibTypeFactory.Void,
+ genericParameterCount: 1,
+ parameterTypes: [
+ _corLibTypeFactory.UInt32,
+ _corLibTypeFactory.Void.MakePointerType().MakePointerType(),
+ Span1.MakeGenericValueType(new GenericParameterSignature(GenericParameterType.Type, 0))]))
+ .MakeGenericInstanceMethod(elementMarshallerType);
+ }
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.WindowsRuntimeKeyValuePairTypeArrayMarshaller<TKey, TValue>.ConvertToUnmanaged<TElementMarshaller>.
+ ///
+ /// The input key type.
+ /// The input value type.
+ /// The element marshaller type.
+ public MethodSpecification WindowsRuntimeKeyValuePairTypeArrayMarshallerConvertToUnmanaged(TypeSignature keyType, TypeSignature valueType, TypeSignature elementMarshallerType)
+ {
+ return WindowsRuntimeKeyValuePairTypeArrayMarshaller2
+ .MakeGenericReferenceType(keyType, valueType)
+ .ToTypeDefOrRef()
+ .CreateMemberReference("ConvertToUnmanaged"u8, MethodSignature.CreateStatic(
+ returnType: _corLibTypeFactory.Void,
+ genericParameterCount: 1,
+ parameterTypes: [
+ ReadOnlySpan1.MakeGenericValueType(
+ KeyValuePair2.MakeGenericValueType(
+ new GenericParameterSignature(GenericParameterType.Type, 0),
+ new GenericParameterSignature(GenericParameterType.Type, 1))),
+ _corLibTypeFactory.UInt32.MakeByReferenceType(),
+ _corLibTypeFactory.Void.MakePointerType().MakePointerType().MakeByReferenceType()]))
+ .MakeGenericInstanceMethod(elementMarshallerType);
+ }
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.WindowsRuntimeKeyValuePairTypeArrayMarshaller<TKey, TValue>.ConvertToManaged<TElementMarshaller>.
+ ///
+ /// The input key type.
+ /// The input value type.
+ /// The element marshaller type.
+ public MethodSpecification WindowsRuntimeKeyValuePairTypeArrayMarshallerConvertToManaged(TypeSignature keyType, TypeSignature valueType, TypeSignature elementMarshallerType)
+ {
+ return WindowsRuntimeKeyValuePairTypeArrayMarshaller2
+ .MakeGenericReferenceType(keyType, valueType)
+ .ToTypeDefOrRef()
+ .CreateMemberReference("ConvertToManaged"u8, MethodSignature.CreateStatic(
+ returnType: KeyValuePair2.MakeGenericValueType(
+ new GenericParameterSignature(GenericParameterType.Type, 0),
+ new GenericParameterSignature(GenericParameterType.Type, 1)).MakeSzArrayType(),
+ genericParameterCount: 1,
+ parameterTypes: [
+ _corLibTypeFactory.UInt32,
+ _corLibTypeFactory.Void.MakePointerType().MakePointerType()]))
+ .MakeGenericInstanceMethod(elementMarshallerType);
+ }
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.WindowsRuntimeKeyValuePairTypeArrayMarshaller<TKey, TValue>.CopyToUnmanaged<TElementMarshaller>.
+ ///
+ /// The input key type.
+ /// The input value type.
+ /// The element marshaller type.
+ public MethodSpecification WindowsRuntimeKeyValuePairTypeArrayMarshallerCopyToUnmanaged(TypeSignature keyType, TypeSignature valueType, TypeSignature elementMarshallerType)
+ {
+ return WindowsRuntimeKeyValuePairTypeArrayMarshaller2
+ .MakeGenericReferenceType(keyType, valueType)
+ .ToTypeDefOrRef()
+ .CreateMemberReference("CopyToUnmanaged"u8, MethodSignature.CreateStatic(
+ returnType: _corLibTypeFactory.Void,
+ genericParameterCount: 1,
+ parameterTypes: [
+ ReadOnlySpan1.MakeGenericValueType(
+ KeyValuePair2.MakeGenericValueType(
+ new GenericParameterSignature(GenericParameterType.Type, 0),
+ new GenericParameterSignature(GenericParameterType.Type, 1))),
+ _corLibTypeFactory.UInt32,
+ _corLibTypeFactory.Void.MakePointerType().MakePointerType()]))
+ .MakeGenericInstanceMethod(elementMarshallerType);
+ }
+
+ ///
+ /// Gets the for WindowsRuntime.InteropServices.Marshalling.WindowsRuntimeKeyValuePairTypeArrayMarshaller<TKey, TValue>.CopyToManaged<TElementMarshaller>.
+ ///
+ /// The input key type.
+ /// The input value type.
+ /// The element marshaller type.
+ public MethodSpecification WindowsRuntimeKeyValuePairTypeArrayMarshallerCopyToManaged(TypeSignature keyType, TypeSignature valueType, TypeSignature elementMarshallerType)
+ {
+ return WindowsRuntimeKeyValuePairTypeArrayMarshaller2
+ .MakeGenericReferenceType(keyType, valueType)
+ .ToTypeDefOrRef()
+ .CreateMemberReference("CopyToManaged"u8, MethodSignature.CreateStatic(
+ returnType: _corLibTypeFactory.Void,
+ genericParameterCount: 1,
+ parameterTypes: [
+ _corLibTypeFactory.UInt32,
+ _corLibTypeFactory.Void.MakePointerType().MakePointerType(),
+ Span1.MakeGenericValueType(
+ KeyValuePair2.MakeGenericValueType(
+ new GenericParameterSignature(GenericParameterType.Type, 0),
+ new GenericParameterSignature(GenericParameterType.Type, 1)))]))
+ .MakeGenericInstanceMethod(elementMarshallerType);
+ }
///
/// Gets the for AddEventHandler for .
diff --git a/src/WinRT.Runtime2/InteropServices/Events/EventSource{T}.cs b/src/WinRT.Runtime2/InteropServices/Events/EventSource{T}.cs
index bffbb9b7f..74befaccb 100644
--- a/src/WinRT.Runtime2/InteropServices/Events/EventSource{T}.cs
+++ b/src/WinRT.Runtime2/InteropServices/Events/EventSource{T}.cs
@@ -88,7 +88,7 @@ public void Subscribe(T? handler)
// That CCW will point the event invoker, ie. a stub on the event source state object.
// This stub captures the event source state, and just invokes the target delegate.
// If we don't need to register the handler, we still just add the new handler here.
- // THe existing CCW will just pick it up the next time the native event is invoked.
+ // The existing CCW will just pick it up the next time the native event is invoked.
state!.AddHandler(handler);
if (registerHandler)
diff --git a/src/WinRT.Runtime2/InteropServices/InteropDllExports/WindowsRuntimeArrayHelpers.cs b/src/WinRT.Runtime2/InteropServices/InteropDllExports/WindowsRuntimeArrayHelpers.cs
deleted file mode 100644
index 904001354..000000000
--- a/src/WinRT.Runtime2/InteropServices/InteropDllExports/WindowsRuntimeArrayHelpers.cs
+++ /dev/null
@@ -1,176 +0,0 @@
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-
-using System;
-using System.ComponentModel;
-using System.Diagnostics;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using WindowsRuntime.InteropServices.Marshalling;
-
-namespace WindowsRuntime.InteropServices;
-
-///
-/// A helper for generated marshaller types for Windows Runtime arrays.
-///
-[Obsolete(WindowsRuntimeConstants.PrivateImplementationDetailObsoleteMessage,
- DiagnosticId = WindowsRuntimeConstants.PrivateImplementationDetailObsoleteDiagnosticId,
- UrlFormat = WindowsRuntimeConstants.CsWinRTDiagnosticsUrlFormat)]
-[EditorBrowsable(EditorBrowsableState.Never)]
-public static unsafe class WindowsRuntimeArrayHelpers
-{
- ///
- /// Validates that the specified destination span has the required number of elements.
- ///
- /// The type of elements in the destination span.
- /// The expected number of elements in the destination span.
- /// The span to validate.
- /// Thrown if the length of does not equal .
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- [StackTraceHidden]
- public static void ValidateDestinationSize(uint size, Span destination)
- {
- if (destination.Length != size)
- {
- [StackTraceHidden]
- static void ThrowArgumentException() => throw new ArgumentException("The destination array is too small.", nameof(destination));
-
- ThrowArgumentException();
- }
- }
-
- ///
- /// Validates that the specified destination span has the required number of elements.
- ///
- /// The type of elements in the destination span.
- /// The span to validate.
- /// The expected number of elements in the destination span.
- /// Thrown if the length of does not equal .
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- [StackTraceHidden]
- public static void ValidateDestinationSize(ReadOnlySpan source, uint size)
- {
- if (source.Length != size)
- {
- [StackTraceHidden]
- static void ThrowArgumentException() => throw new ArgumentException("The destination array is too small.", "destination");
-
- ThrowArgumentException();
- }
- }
-
- ///
- /// Frees an HSTRING reference array.
- ///
- /// The size of the array.
- /// The input array.
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static void FreeHStringArrayUnsafe(uint size, HSTRING* array)
- {
- if (size == 0)
- {
- return;
- }
-
- ArgumentNullException.ThrowIfNull(array);
-
- for (int i = 0; i < size; i++)
- {
- HStringMarshaller.Free(array[i]);
- }
-
- Marshal.FreeCoTaskMem((nint)array);
- }
-
- ///
- /// Frees an object reference array.
- ///
- /// The size of the array.
- /// The input array.
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static void FreeObjectArrayUnsafe(uint size, void** array)
- {
- if (size == 0)
- {
- return;
- }
-
- ArgumentNullException.ThrowIfNull(array);
-
- for (int i = 0; i < size; i++)
- {
- WindowsRuntimeUnknownMarshaller.Free(array[i]);
- }
-
- Marshal.FreeCoTaskMem((nint)array);
- }
-
- ///
- /// Frees a reference array of values.
- ///
- /// The size of the array.
- /// The input array.
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static void FreeTypeArrayUnsafe(uint size, ABI.System.Type* array)
- {
- if (size == 0)
- {
- return;
- }
-
- ArgumentNullException.ThrowIfNull(array);
-
- for (int i = 0; i < size; i++)
- {
- HStringMarshaller.Free(array[i].Name);
- }
-
- Marshal.FreeCoTaskMem((nint)array);
- }
-
- ///
- /// Frees a reference array of some blittable type.
- ///
- /// The size of the array.
- /// The input array.
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static void FreeBlittableArrayUnsafe(uint size, void* array)
- {
- if (size == 0)
- {
- return;
- }
-
- ArgumentNullException.ThrowIfNull(array);
-
- Marshal.FreeCoTaskMem((nint)array);
- }
-
- ///
- /// Frees a range of an HSTRING reference array.
- ///
- /// The offset to free the array up to.
- /// The input array.
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static void FreeHStringRangeUnsafe(int offset, HSTRING* array)
- {
- for (int i = 0; i < offset; i++)
- {
- HStringMarshaller.Free(array[i]);
- }
- }
-
- ///
- /// Frees a range of an object reference array.
- ///
- /// The offset to free the array up to.
- /// The input array.
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static void FreeObjectRangeUnsafe(int offset, void** array)
- {
- for (int i = 0; i < offset; i++)
- {
- WindowsRuntimeUnknownMarshaller.Free(array[i]);
- }
- }
-}
\ No newline at end of file
diff --git a/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/ExceptionArrayMarshaller.cs b/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/ExceptionArrayMarshaller.cs
new file mode 100644
index 000000000..ff19124bc
--- /dev/null
+++ b/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/ExceptionArrayMarshaller.cs
@@ -0,0 +1,120 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System;
+using System.ComponentModel;
+using System.Runtime.InteropServices;
+
+namespace WindowsRuntime.InteropServices.Marshalling;
+
+///
+/// A marshaller for arrays of the Windows Runtime type.
+///
+[Obsolete(WindowsRuntimeConstants.PrivateImplementationDetailObsoleteMessage,
+ DiagnosticId = WindowsRuntimeConstants.PrivateImplementationDetailObsoleteDiagnosticId,
+ UrlFormat = WindowsRuntimeConstants.CsWinRTDiagnosticsUrlFormat)]
+[EditorBrowsable(EditorBrowsableState.Never)]
+public static unsafe class ExceptionArrayMarshaller
+{
+ ///
+ public static void ConvertToUnmanaged(ReadOnlySpan source, out uint size, out ABI.System.Exception* array)
+ {
+ if (source.IsEmpty)
+ {
+ size = 0;
+ array = null;
+
+ return;
+ }
+
+ ABI.System.Exception* destination = (ABI.System.Exception*)Marshal.AllocCoTaskMem(sizeof(ABI.System.Exception) * source.Length);
+
+ try
+ {
+ // Marshal all input 'Exception'-s with 'ExceptionMarshaller' (note that 'HResult' is blittable)
+ for (int i = 0; i < source.Length; i++)
+ {
+ destination[i] = ABI.System.ExceptionMarshaller.ConvertToUnmanaged(source[i]);
+ }
+ }
+ catch
+ {
+ // Release the allocated array to avoid leaking (this shouldn't really happen)
+ Marshal.FreeCoTaskMem((nint)destination);
+
+ throw;
+ }
+
+ size = (uint)source.Length;
+ array = destination;
+ }
+
+ ///
+ public static Exception?[] ConvertToManaged(uint size, ABI.System.Exception* value)
+ {
+ if (size == 0)
+ {
+ return [];
+ }
+
+ ArgumentNullException.ThrowIfNull(value);
+
+ Exception?[] array = new Exception[(int)size];
+
+ for (int i = 0; i < size; i++)
+ {
+ array[i] = ABI.System.ExceptionMarshaller.ConvertToManaged(value[i]);
+ }
+
+ return array;
+ }
+
+ ///
+ public static void CopyToUnmanaged(ReadOnlySpan source, uint size, ABI.System.Exception* destination)
+ {
+ WindowsRuntimeArrayMarshallerHelpers.ValidateDestinationSize(source.Length, size);
+
+ if (size == 0)
+ {
+ return;
+ }
+
+ ArgumentNullException.ThrowIfNull(destination);
+
+ for (int i = 0; i < source.Length; i++)
+ {
+ destination[i] = ABI.System.ExceptionMarshaller.ConvertToUnmanaged(source[i]);
+ }
+ }
+
+ ///
+ public static void CopyToManaged(uint size, ABI.System.Exception* source, Span destination)
+ {
+ WindowsRuntimeArrayMarshallerHelpers.ValidateDestinationSize(size, destination.Length);
+
+ if (size == 0)
+ {
+ return;
+ }
+
+ ArgumentNullException.ThrowIfNull(source);
+
+ for (uint i = 0; i < size; i++)
+ {
+ destination[(int)i] = ABI.System.ExceptionMarshaller.ConvertToManaged(source[i]);
+ }
+ }
+
+ ///
+ public static void Free(uint size, ABI.System.Exception* array)
+ {
+ if (size == 0)
+ {
+ return;
+ }
+
+ ArgumentNullException.ThrowIfNull(array);
+
+ Marshal.FreeCoTaskMem((nint)array);
+ }
+}
\ No newline at end of file
diff --git a/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/HStringArrayMarshaller.cs b/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/HStringArrayMarshaller.cs
new file mode 100644
index 000000000..14a06083d
--- /dev/null
+++ b/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/HStringArrayMarshaller.cs
@@ -0,0 +1,149 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System;
+using System.ComponentModel;
+using System.Runtime.InteropServices;
+
+namespace WindowsRuntime.InteropServices.Marshalling;
+
+///
+/// A marshaller for arrays of the Windows Runtime HSTRING type.
+///
+[Obsolete(WindowsRuntimeConstants.PrivateImplementationDetailObsoleteMessage,
+ DiagnosticId = WindowsRuntimeConstants.PrivateImplementationDetailObsoleteDiagnosticId,
+ UrlFormat = WindowsRuntimeConstants.CsWinRTDiagnosticsUrlFormat)]
+[EditorBrowsable(EditorBrowsableState.Never)]
+public static unsafe class HStringArrayMarshaller
+{
+ ///
+ public static void ConvertToUnmanaged(ReadOnlySpan source, out uint size, out void** array)
+ {
+ if (source.IsEmpty)
+ {
+ size = 0;
+ array = null;
+
+ return;
+ }
+
+ void** destination = (void**)Marshal.AllocCoTaskMem(sizeof(void*) * source.Length);
+
+ int i = 0;
+
+ try
+ {
+ // Marshal all input 'string'-s with 'HStringMarshaller' (note that 'HSTRING' is not a COM object)
+ for (; i < source.Length; i++)
+ {
+ destination[i] = HStringMarshaller.ConvertToUnmanaged(source[i]);
+ }
+ }
+ catch
+ {
+ // Make sure to release all marshalled objects so far (this shouldn't ever throw)
+ for (int j = 0; j < i; j++)
+ {
+ HStringMarshaller.Free(destination[j]);
+ }
+
+ // Also release the allocated array to avoid leaking
+ Marshal.FreeCoTaskMem((nint)destination);
+
+ throw;
+ }
+
+ size = (uint)source.Length;
+ array = destination;
+ }
+
+ ///
+ public static string[] ConvertToManaged(uint size, void** value)
+ {
+ if (size == 0)
+ {
+ return [];
+ }
+
+ ArgumentNullException.ThrowIfNull(value);
+
+ string[] array = new string[(int)size];
+
+ for (int i = 0; i < size; i++)
+ {
+ array[i] = HStringMarshaller.ConvertToManaged(value[i]);
+ }
+
+ return array;
+ }
+
+ ///
+ public static void CopyToUnmanaged(ReadOnlySpan source, uint size, void** destination)
+ {
+ WindowsRuntimeArrayMarshallerHelpers.ValidateDestinationSize(source.Length, size);
+
+ if (size == 0)
+ {
+ return;
+ }
+
+ ArgumentNullException.ThrowIfNull(destination);
+
+ int i = 0;
+
+ try
+ {
+ // Marshal the items in the input span
+ for (; i < source.Length; i++)
+ {
+ destination[i] = HStringMarshaller.ConvertToUnmanaged(source[i]);
+ }
+ }
+ catch
+ {
+ // Release resources for any items, if we failed
+ for (int j = 0; j < i; j++)
+ {
+ HStringMarshaller.Free(destination[j]);
+ }
+
+ throw;
+ }
+ }
+
+ ///
+ public static void CopyToManaged(uint size, void** source, Span destination)
+ {
+ WindowsRuntimeArrayMarshallerHelpers.ValidateDestinationSize(size, destination.Length);
+
+ if (size == 0)
+ {
+ return;
+ }
+
+ ArgumentNullException.ThrowIfNull(source);
+
+ for (uint i = 0; i < size; i++)
+ {
+ destination[(int)i] = HStringMarshaller.ConvertToManaged(source[i]);
+ }
+ }
+
+ ///
+ public static void Free(uint size, void** array)
+ {
+ if (size == 0)
+ {
+ return;
+ }
+
+ ArgumentNullException.ThrowIfNull(array);
+
+ for (uint i = 0; i < size; i++)
+ {
+ HStringMarshaller.Free(array[i]);
+ }
+
+ Marshal.FreeCoTaskMem((nint)array);
+ }
+}
\ No newline at end of file
diff --git a/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/IWindowsRuntimeKeyValuePairTypeArrayElementMarshaller{TKey, TValue}.cs b/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/IWindowsRuntimeKeyValuePairTypeArrayElementMarshaller{TKey, TValue}.cs
new file mode 100644
index 000000000..2c6d04021
--- /dev/null
+++ b/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/IWindowsRuntimeKeyValuePairTypeArrayElementMarshaller{TKey, TValue}.cs
@@ -0,0 +1,34 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+
+namespace WindowsRuntime.InteropServices.Marshalling;
+
+///
+/// An interface for marshalling implementations to support .
+///
+/// The type of the key.
+/// The type of the value.
+[Obsolete(WindowsRuntimeConstants.PrivateImplementationDetailObsoleteMessage,
+ DiagnosticId = WindowsRuntimeConstants.PrivateImplementationDetailObsoleteDiagnosticId,
+ UrlFormat = WindowsRuntimeConstants.CsWinRTDiagnosticsUrlFormat)]
+[EditorBrowsable(EditorBrowsableState.Never)]
+public unsafe interface IWindowsRuntimeKeyValuePairTypeArrayElementMarshaller
+{
+ ///
+ /// Marshals a type to its native Windows Runtime representation.
+ ///
+ /// The input value to marshal.
+ /// The marshalled native value.
+ static abstract WindowsRuntimeObjectReferenceValue ConvertToUnmanaged(KeyValuePair value);
+
+ ///
+ /// Marshals a native Windows Runtime type to its managed representation.
+ ///
+ /// The input value to marshal.
+ /// The marshalled managed value.
+ static abstract KeyValuePair ConvertToManaged(void* value);
+}
diff --git a/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/IWindowsRuntimeManagedValueTypeArrayElementMarshaller{T, TAbi}.cs b/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/IWindowsRuntimeManagedValueTypeArrayElementMarshaller{T, TAbi}.cs
new file mode 100644
index 000000000..1f2052b0a
--- /dev/null
+++ b/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/IWindowsRuntimeManagedValueTypeArrayElementMarshaller{T, TAbi}.cs
@@ -0,0 +1,41 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System;
+using System.ComponentModel;
+
+namespace WindowsRuntime.InteropServices.Marshalling;
+
+///
+/// An interface for marshalling implementations to support .
+///
+/// The type of elements in the array.
+/// The ABI type for type .
+[Obsolete(WindowsRuntimeConstants.PrivateImplementationDetailObsoleteMessage,
+ DiagnosticId = WindowsRuntimeConstants.PrivateImplementationDetailObsoleteDiagnosticId,
+ UrlFormat = WindowsRuntimeConstants.CsWinRTDiagnosticsUrlFormat)]
+[EditorBrowsable(EditorBrowsableState.Never)]
+public interface IWindowsRuntimeManagedValueTypeArrayElementMarshaller
+ where T : struct
+ where TAbi : unmanaged
+{
+ ///
+ /// Marshals an unmanaged Windows Runtime value type to its native representation.
+ ///
+ /// The input value to marshal.
+ /// The marshalled native value.
+ static abstract TAbi ConvertToUnmanaged(T value);
+
+ ///
+ /// Marshals a native Windows Runtime value type to its managed representation.
+ ///
+ /// The input value to marshal.
+ /// The marshalled managed value.
+ static abstract T ConvertToManaged(TAbi value);
+
+ ///
+ /// Disposes resources associated with an unmanaged value.
+ ///
+ /// The unmanaged value to dispose.
+ static abstract void Dispose(TAbi value);
+}
diff --git a/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/IWindowsRuntimeReferenceTypeArrayElementMarshaller{T}.cs b/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/IWindowsRuntimeReferenceTypeArrayElementMarshaller{T}.cs
new file mode 100644
index 000000000..bd913731f
--- /dev/null
+++ b/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/IWindowsRuntimeReferenceTypeArrayElementMarshaller{T}.cs
@@ -0,0 +1,33 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System;
+using System.ComponentModel;
+
+namespace WindowsRuntime.InteropServices.Marshalling;
+
+///
+/// An interface for marshalling implementations to support .
+///
+/// The type of elements in the array.
+[Obsolete(WindowsRuntimeConstants.PrivateImplementationDetailObsoleteMessage,
+ DiagnosticId = WindowsRuntimeConstants.PrivateImplementationDetailObsoleteDiagnosticId,
+ UrlFormat = WindowsRuntimeConstants.CsWinRTDiagnosticsUrlFormat)]
+[EditorBrowsable(EditorBrowsableState.Never)]
+public unsafe interface IWindowsRuntimeReferenceTypeArrayElementMarshaller
+ where T : class
+{
+ ///
+ /// Marshals a Windows Runtime object to a instance.
+ ///
+ /// The input object to marshal.
+ /// A instance for .
+ static abstract WindowsRuntimeObjectReferenceValue ConvertToUnmanaged(T? value);
+
+ ///
+ /// Converts an unmanaged pointer to a Windows Runtime object to a managed object.
+ ///
+ /// The input object to convert to managed.
+ /// The resulting managed object.
+ static abstract T? ConvertToManaged(void* value);
+}
diff --git a/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/IWindowsRuntimeUnmanagedValueTypeArrayElementMarshaller{T, TAbi}.cs b/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/IWindowsRuntimeUnmanagedValueTypeArrayElementMarshaller{T, TAbi}.cs
new file mode 100644
index 000000000..11743faf1
--- /dev/null
+++ b/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/IWindowsRuntimeUnmanagedValueTypeArrayElementMarshaller{T, TAbi}.cs
@@ -0,0 +1,35 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System;
+using System.ComponentModel;
+
+namespace WindowsRuntime.InteropServices.Marshalling;
+
+///
+/// An interface for marshalling implementations to support .
+///
+/// The type of elements in the array.
+/// The ABI type for type .
+[Obsolete(WindowsRuntimeConstants.PrivateImplementationDetailObsoleteMessage,
+ DiagnosticId = WindowsRuntimeConstants.PrivateImplementationDetailObsoleteDiagnosticId,
+ UrlFormat = WindowsRuntimeConstants.CsWinRTDiagnosticsUrlFormat)]
+[EditorBrowsable(EditorBrowsableState.Never)]
+public interface IWindowsRuntimeUnmanagedValueTypeArrayElementMarshaller
+ where T : unmanaged
+ where TAbi : unmanaged
+{
+ ///
+ /// Marshals an unmanaged Windows Runtime value type to its native representation.
+ ///
+ /// The input value to marshal.
+ /// The marshalled native value.
+ static abstract TAbi ConvertToUnmanaged(T value);
+
+ ///
+ /// Marshals a native Windows Runtime value type to its managed representation.
+ ///
+ /// The input value to marshal.
+ /// The marshalled managed value.
+ static abstract T ConvertToManaged(TAbi value);
+}
diff --git a/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/TypeArrayMarshaller.cs b/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/TypeArrayMarshaller.cs
new file mode 100644
index 000000000..b68e117da
--- /dev/null
+++ b/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/TypeArrayMarshaller.cs
@@ -0,0 +1,149 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System;
+using System.ComponentModel;
+using System.Runtime.InteropServices;
+
+namespace WindowsRuntime.InteropServices.Marshalling;
+
+///
+/// A marshaller for arrays of the Windows Runtime type.
+///
+[Obsolete(WindowsRuntimeConstants.PrivateImplementationDetailObsoleteMessage,
+ DiagnosticId = WindowsRuntimeConstants.PrivateImplementationDetailObsoleteDiagnosticId,
+ UrlFormat = WindowsRuntimeConstants.CsWinRTDiagnosticsUrlFormat)]
+[EditorBrowsable(EditorBrowsableState.Never)]
+public static unsafe class TypeArrayMarshaller
+{
+ ///
+ public static void ConvertToUnmanaged(ReadOnlySpan source, out uint size, out ABI.System.Type* array)
+ {
+ if (source.IsEmpty)
+ {
+ size = 0;
+ array = null;
+
+ return;
+ }
+
+ ABI.System.Type* destination = (ABI.System.Type*)Marshal.AllocCoTaskMem(sizeof(ABI.System.Type) * source.Length);
+
+ int i = 0;
+
+ try
+ {
+ // Marshal all input 'Type' objects with its marshaller (note the ABI type will be a value type)
+ for (; i < source.Length; i++)
+ {
+ destination[i] = ABI.System.TypeMarshaller.ConvertToUnmanaged(source[i]);
+ }
+ }
+ catch
+ {
+ // Dispose each ABI value (it contains an 'HSTRING' which we should release)
+ for (int j = 0; j < i; j++)
+ {
+ ABI.System.TypeMarshaller.Dispose(destination[j]);
+ }
+
+ // Also release the allocated array to avoid leaking
+ Marshal.FreeCoTaskMem((nint)destination);
+
+ throw;
+ }
+
+ size = (uint)source.Length;
+ array = destination;
+ }
+
+ ///
+ public static Type?[] ConvertToManaged(uint size, ABI.System.Type* value)
+ {
+ if (size == 0)
+ {
+ return [];
+ }
+
+ ArgumentNullException.ThrowIfNull(value);
+
+ Type?[] array = new Type[(int)size];
+
+ for (int i = 0; i < size; i++)
+ {
+ array[i] = ABI.System.TypeMarshaller.ConvertToManaged(value[i]);
+ }
+
+ return array;
+ }
+
+ ///
+ public static void CopyToUnmanaged(ReadOnlySpan source, uint size, ABI.System.Type* destination)
+ {
+ WindowsRuntimeArrayMarshallerHelpers.ValidateDestinationSize(source.Length, size);
+
+ if (size == 0)
+ {
+ return;
+ }
+
+ ArgumentNullException.ThrowIfNull(destination);
+
+ int i = 0;
+
+ try
+ {
+ // Marshal the items in the input span
+ for (; i < source.Length; i++)
+ {
+ destination[i] = ABI.System.TypeMarshaller.ConvertToUnmanaged(source[i]);
+ }
+ }
+ catch
+ {
+ // Release resources for any items, if we failed
+ for (int j = 0; j < i; j++)
+ {
+ ABI.System.TypeMarshaller.Dispose(destination[j]);
+ }
+
+ throw;
+ }
+ }
+
+ ///
+ public static void CopyToManaged(uint size, ABI.System.Type* source, Span destination)
+ {
+ WindowsRuntimeArrayMarshallerHelpers.ValidateDestinationSize(size, destination.Length);
+
+ if (size == 0)
+ {
+ return;
+ }
+
+ ArgumentNullException.ThrowIfNull(source);
+
+ for (uint i = 0; i < size; i++)
+ {
+ destination[(int)i] = ABI.System.TypeMarshaller.ConvertToManaged(source[i]);
+ }
+ }
+
+ ///
+ public static void Free(uint size, ABI.System.Type* array)
+ {
+ if (size == 0)
+ {
+ return;
+ }
+
+ ArgumentNullException.ThrowIfNull(array);
+
+ for (uint i = 0; i < size; i++)
+ {
+ ABI.System.TypeMarshaller.Dispose(array[i]);
+ }
+
+ Marshal.FreeCoTaskMem((nint)array);
+ }
+}
\ No newline at end of file
diff --git a/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/WindowsRuntimeArrayMarshallerHelpers.cs b/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/WindowsRuntimeArrayMarshallerHelpers.cs
new file mode 100644
index 000000000..f8f75c654
--- /dev/null
+++ b/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/WindowsRuntimeArrayMarshallerHelpers.cs
@@ -0,0 +1,54 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+
+#pragma warning disable CA2208
+
+namespace WindowsRuntime.InteropServices.Marshalling;
+
+///
+/// A helper for marshaller types for Windows Runtime arrays.
+///
+internal static unsafe class WindowsRuntimeArrayMarshallerHelpers
+{
+ ///
+ /// Validates that the specified destination span has the required number of elements.
+ ///
+ /// The expected number of elements in the destination span.
+ /// The length of the destination span.
+ /// Thrown if does not equal .
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [StackTraceHidden]
+ public static void ValidateDestinationSize(uint sourceSize, int destinationSize)
+ {
+ if ((uint)destinationSize != sourceSize)
+ {
+ [StackTraceHidden]
+ static void ThrowArgumentException() => throw new ArgumentException("The destination array is too small.", "destination");
+
+ ThrowArgumentException();
+ }
+ }
+
+ ///
+ /// Validates that the specified destination span has the required number of elements.
+ ///
+ /// The length of the span to validate.
+ /// The expected number of elements in the destination span.
+ /// Thrown if does not equal .
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [StackTraceHidden]
+ public static void ValidateDestinationSize(int sourceSize, uint destinationSize)
+ {
+ if ((uint)sourceSize != destinationSize)
+ {
+ [StackTraceHidden]
+ static void ThrowArgumentException() => throw new ArgumentException("The destination array is too small.", "destination");
+
+ ThrowArgumentException();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/WindowsRuntimeBlittableValueTypeArrayMarshaller{T}.cs b/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/WindowsRuntimeBlittableValueTypeArrayMarshaller{T}.cs
new file mode 100644
index 000000000..bc9610774
--- /dev/null
+++ b/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/WindowsRuntimeBlittableValueTypeArrayMarshaller{T}.cs
@@ -0,0 +1,117 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System;
+using System.ComponentModel;
+using System.Runtime.InteropServices;
+
+namespace WindowsRuntime.InteropServices.Marshalling;
+
+///
+/// A marshaller for arrays of blittable Windows Runtime types.
+///
+/// The type of elements in the array.
+[Obsolete(WindowsRuntimeConstants.PrivateImplementationDetailObsoleteMessage,
+ DiagnosticId = WindowsRuntimeConstants.PrivateImplementationDetailObsoleteDiagnosticId,
+ UrlFormat = WindowsRuntimeConstants.CsWinRTDiagnosticsUrlFormat)]
+[EditorBrowsable(EditorBrowsableState.Never)]
+public static unsafe class WindowsRuntimeBlittableValueTypeArrayMarshaller
+ where T : unmanaged
+{
+ ///
+ /// Marshals a managed array to an unmanaged Windows Runtime array.
+ ///
+ /// The source array.
+ /// The size of the array.
+ /// The resulting Windows Runtime array.
+ public static void ConvertToUnmanaged(ReadOnlySpan source, out uint size, out T* array)
+ {
+ if (source.IsEmpty)
+ {
+ size = 0;
+ array = null;
+
+ return;
+ }
+
+ size = (uint)source.Length;
+ array = (T*)Marshal.AllocCoTaskMem(sizeof(T) * source.Length);
+
+ source.CopyTo(new Span(array, source.Length));
+ }
+
+ ///
+ /// Marshals an unmanaged Windows Runtime array to a managed array.
+ ///
+ /// The size of the array.
+ /// The source array.
+ /// The resulting managed array.
+ public static T[] ConvertToManaged(uint size, T* value)
+ {
+ if (size == 0)
+ {
+ return [];
+ }
+
+ ArgumentNullException.ThrowIfNull(value);
+
+ return new ReadOnlySpan(value, (int)size).ToArray();
+ }
+
+ ///
+ /// Copies items from a managed array to the target unmanaged Windows Runtime array.
+ ///
+ /// The source array.
+ /// The size of the array.
+ /// The destination array.
+ public static void CopyToUnmanaged(ReadOnlySpan source, uint size, T* destination)
+ {
+ WindowsRuntimeArrayMarshallerHelpers.ValidateDestinationSize(source.Length, size);
+
+ if (size == 0)
+ {
+ return;
+ }
+
+ ArgumentNullException.ThrowIfNull(destination);
+
+ source.CopyTo(new Span(destination, (int)size));
+ }
+
+ ///
+ /// Copies items from an unmanaged Windows Runtime array to the target managed array.
+ ///
+ /// The size of the array.
+ /// The source array.
+ /// The destination array.
+ public static void CopyToManaged(uint size, T* source, Span destination)
+ {
+ WindowsRuntimeArrayMarshallerHelpers.ValidateDestinationSize(size, destination.Length);
+
+ if (size == 0)
+ {
+ return;
+ }
+
+ ArgumentNullException.ThrowIfNull(source);
+
+ new ReadOnlySpan(source, (int)size).CopyTo(destination);
+ }
+
+ ///
+ /// Frees the specified array.
+ ///
+ /// The size of the array.
+ /// The input array.
+ public static void Free(uint size, T* array)
+ {
+ if (size == 0)
+ {
+ return;
+ }
+
+ ArgumentNullException.ThrowIfNull(array);
+
+ Marshal.FreeCoTaskMem((nint)array);
+ }
+}
\ No newline at end of file
diff --git a/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/WindowsRuntimeKeyValuePairTypeArrayMarshaller{TKey, TValue}.cs b/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/WindowsRuntimeKeyValuePairTypeArrayMarshaller{TKey, TValue}.cs
new file mode 100644
index 000000000..ec3e5089c
--- /dev/null
+++ b/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/WindowsRuntimeKeyValuePairTypeArrayMarshaller{TKey, TValue}.cs
@@ -0,0 +1,142 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Runtime.InteropServices;
+
+namespace WindowsRuntime.InteropServices.Marshalling;
+
+///
+/// A marshaller for arrays of types.
+///
+/// The type of the key.
+/// The type of the value.
+[Obsolete(WindowsRuntimeConstants.PrivateImplementationDetailObsoleteMessage,
+ DiagnosticId = WindowsRuntimeConstants.PrivateImplementationDetailObsoleteDiagnosticId,
+ UrlFormat = WindowsRuntimeConstants.CsWinRTDiagnosticsUrlFormat)]
+[EditorBrowsable(EditorBrowsableState.Never)]
+public static unsafe class WindowsRuntimeKeyValuePairTypeArrayMarshaller
+{
+ ///
+ /// The type of marshaller for each managed array element.
+ public static void ConvertToUnmanaged(ReadOnlySpan> source, out uint size, out void** array)
+ where TElementMarshaller : IWindowsRuntimeKeyValuePairTypeArrayElementMarshaller
+ {
+ if (source.IsEmpty)
+ {
+ size = 0;
+ array = null;
+
+ return;
+ }
+
+ void** destination = (void**)Marshal.AllocCoTaskMem(sizeof(void*) * source.Length);
+
+ int i = 0;
+
+ try
+ {
+ // Marshal all array elements (the ABI type for 'KeyValuePair<,>' is just 'void*')
+ for (; i < source.Length; i++)
+ {
+ destination[i] = TElementMarshaller.ConvertToUnmanaged(source[i]).DetachThisPtrUnsafe();
+ }
+ }
+ catch
+ {
+ // Release any allocated native 'IKeyValuePair<,>' values
+ for (int j = 0; j < i; j++)
+ {
+ WindowsRuntimeUnknownMarshaller.Free(destination[j]);
+ }
+
+ // Also release the allocated array to avoid leaking
+ Marshal.FreeCoTaskMem((nint)destination);
+
+ throw;
+ }
+
+ size = (uint)source.Length;
+ array = destination;
+ }
+
+ ///
+ /// The type of marshaller for each managed array element.
+ public static KeyValuePair[] ConvertToManaged(uint size, void** value)
+ where TElementMarshaller : IWindowsRuntimeKeyValuePairTypeArrayElementMarshaller
+ {
+ if (size == 0)
+ {
+ return [];
+ }
+
+ ArgumentNullException.ThrowIfNull(value);
+
+ KeyValuePair[] array = new KeyValuePair[(int)size];
+
+ for (int i = 0; i < size; i++)
+ {
+ array[i] = TElementMarshaller.ConvertToManaged(value[i]);
+ }
+
+ return array;
+ }
+
+ ///
+ /// The type of marshaller for each managed array element.
+ public static void CopyToUnmanaged(ReadOnlySpan> source, uint size, void** destination)
+ where TElementMarshaller : IWindowsRuntimeKeyValuePairTypeArrayElementMarshaller
+ {
+ WindowsRuntimeArrayMarshallerHelpers.ValidateDestinationSize(source.Length, size);
+
+ if (size == 0)
+ {
+ return;
+ }
+
+ ArgumentNullException.ThrowIfNull(destination);
+
+ int i = 0;
+
+ try
+ {
+ // Marshal the items in the input span
+ for (; i < source.Length; i++)
+ {
+ destination[i] = TElementMarshaller.ConvertToUnmanaged(source[i]).DetachThisPtrUnsafe();
+ }
+ }
+ catch
+ {
+ // Release resources for any items, if we failed
+ for (int j = 0; j < i; j++)
+ {
+ WindowsRuntimeUnknownMarshaller.Free(destination[j]);
+ }
+
+ throw;
+ }
+ }
+
+ ///
+ /// The type of marshaller for each managed array element.
+ public static void CopyToManaged(uint size, void** source, Span> destination)
+ where TElementMarshaller : IWindowsRuntimeKeyValuePairTypeArrayElementMarshaller
+ {
+ WindowsRuntimeArrayMarshallerHelpers.ValidateDestinationSize(size, destination.Length);
+
+ if (size == 0)
+ {
+ return;
+ }
+
+ ArgumentNullException.ThrowIfNull(source);
+
+ for (uint i = 0; i < size; i++)
+ {
+ destination[(int)i] = TElementMarshaller.ConvertToManaged(source[i]);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/WindowsRuntimeManagedValueTypeArrayMarshaller{T, TAbi}.cs b/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/WindowsRuntimeManagedValueTypeArrayMarshaller{T, TAbi}.cs
new file mode 100644
index 000000000..209127fb6
--- /dev/null
+++ b/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/WindowsRuntimeManagedValueTypeArrayMarshaller{T, TAbi}.cs
@@ -0,0 +1,164 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System;
+using System.ComponentModel;
+using System.Runtime.InteropServices;
+
+namespace WindowsRuntime.InteropServices.Marshalling;
+
+///
+/// A marshaller for arrays of managed Windows Runtime types.
+///
+/// The type of elements in the array.
+/// The ABI type for type .
+[Obsolete(WindowsRuntimeConstants.PrivateImplementationDetailObsoleteMessage,
+ DiagnosticId = WindowsRuntimeConstants.PrivateImplementationDetailObsoleteDiagnosticId,
+ UrlFormat = WindowsRuntimeConstants.CsWinRTDiagnosticsUrlFormat)]
+[EditorBrowsable(EditorBrowsableState.Never)]
+public static unsafe class WindowsRuntimeManagedValueTypeArrayMarshaller
+ where T : struct
+ where TAbi : unmanaged
+{
+ ///
+ /// The type of marshaller for each managed array element.
+ public static void ConvertToUnmanaged(ReadOnlySpan source, out uint size, out TAbi* array)
+ where TElementMarshaller : IWindowsRuntimeManagedValueTypeArrayElementMarshaller
+ {
+ if (source.IsEmpty)
+ {
+ size = 0;
+ array = null;
+
+ return;
+ }
+
+ TAbi* destination = (TAbi*)Marshal.AllocCoTaskMem(sizeof(T) * source.Length);
+
+ int i = 0;
+
+ try
+ {
+ // Marshal all array elements with the provided element marshaller.
+ // Because the native type contains resources, this might throw.
+ for (; i < source.Length; i++)
+ {
+ destination[i] = TElementMarshaller.ConvertToUnmanaged(source[i]);
+ }
+ }
+ catch
+ {
+ // Make sure to release all native resources for marshalled values
+ for (int j = 0; j < i; j++)
+ {
+ TElementMarshaller.Dispose(destination[j]);
+ }
+
+ // Also release the allocated array to avoid leaking
+ Marshal.FreeCoTaskMem((nint)destination);
+
+ throw;
+ }
+
+ size = (uint)source.Length;
+ array = destination;
+ }
+
+ ///
+ /// The type of marshaller for each managed array element.
+ public static T[] ConvertToManaged(uint size, TAbi* value)
+ where TElementMarshaller : IWindowsRuntimeManagedValueTypeArrayElementMarshaller
+ {
+ if (size == 0)
+ {
+ return [];
+ }
+
+ ArgumentNullException.ThrowIfNull(value);
+
+ T[] array = GC.AllocateUninitializedArray((int)size);
+
+ for (int i = 0; i < size; i++)
+ {
+ array[i] = TElementMarshaller.ConvertToManaged(value[i]);
+ }
+
+ return array;
+ }
+
+ ///
+ /// The type of marshaller for each managed array element.
+ public static void CopyToUnmanaged(ReadOnlySpan source, uint size, TAbi* destination)
+ where TElementMarshaller : IWindowsRuntimeManagedValueTypeArrayElementMarshaller
+ {
+ WindowsRuntimeArrayMarshallerHelpers.ValidateDestinationSize(source.Length, size);
+
+ if (size == 0)
+ {
+ return;
+ }
+
+ ArgumentNullException.ThrowIfNull(destination);
+
+ int i = 0;
+
+ try
+ {
+ // Marshal the items in the input span
+ for (; i < source.Length; i++)
+ {
+ destination[i] = TElementMarshaller.ConvertToUnmanaged(source[i]);
+ }
+ }
+ catch
+ {
+ // Release resources for any items, if we failed
+ for (int j = 0; j < i; j++)
+ {
+ TElementMarshaller.Dispose(destination[j]);
+ }
+
+ throw;
+ }
+ }
+
+ ///
+ /// The type of marshaller for each managed array element.
+ public static void CopyToManaged(uint size, TAbi* source, Span destination)
+ where TElementMarshaller : IWindowsRuntimeManagedValueTypeArrayElementMarshaller
+ {
+ WindowsRuntimeArrayMarshallerHelpers.ValidateDestinationSize(size, destination.Length);
+
+ if (size == 0)
+ {
+ return;
+ }
+
+ ArgumentNullException.ThrowIfNull(source);
+
+ for (uint i = 0; i < size; i++)
+ {
+ destination[(int)i] = TElementMarshaller.ConvertToManaged(source[i]);
+ }
+ }
+
+ ///
+ /// The type of marshaller for each managed array element.
+ public static void Free(uint size, TAbi* array)
+ where TElementMarshaller : IWindowsRuntimeManagedValueTypeArrayElementMarshaller
+ {
+ if (size == 0)
+ {
+ return;
+ }
+
+ ArgumentNullException.ThrowIfNull(array);
+
+ for (int i = 0; i < size; i++)
+ {
+ TElementMarshaller.Dispose(array[i]);
+ }
+
+ Marshal.FreeCoTaskMem((nint)array);
+ }
+}
\ No newline at end of file
diff --git a/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/WindowsRuntimeReferenceTypeArrayMarshaller{T}.cs b/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/WindowsRuntimeReferenceTypeArrayMarshaller{T}.cs
new file mode 100644
index 000000000..0ca314f15
--- /dev/null
+++ b/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/WindowsRuntimeReferenceTypeArrayMarshaller{T}.cs
@@ -0,0 +1,141 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System;
+using System.ComponentModel;
+using System.Runtime.InteropServices;
+
+namespace WindowsRuntime.InteropServices.Marshalling;
+
+///
+/// A marshaller for arrays of reference Windows Runtime types.
+///
+/// The type of elements in the array.
+[Obsolete(WindowsRuntimeConstants.PrivateImplementationDetailObsoleteMessage,
+ DiagnosticId = WindowsRuntimeConstants.PrivateImplementationDetailObsoleteDiagnosticId,
+ UrlFormat = WindowsRuntimeConstants.CsWinRTDiagnosticsUrlFormat)]
+[EditorBrowsable(EditorBrowsableState.Never)]
+public static unsafe class WindowsRuntimeReferenceTypeArrayMarshaller
+ where T : class
+{
+ ///
+ /// The type of marshaller for each managed array element.
+ public static void ConvertToUnmanaged(ReadOnlySpan source, out uint size, out void** array)
+ where TElementMarshaller : IWindowsRuntimeReferenceTypeArrayElementMarshaller
+ {
+ if (source.IsEmpty)
+ {
+ size = 0;
+ array = null;
+
+ return;
+ }
+
+ void** destination = (void**)Marshal.AllocCoTaskMem(sizeof(void*) * source.Length);
+
+ int i = 0;
+
+ try
+ {
+ // Marshal all array elements with the provided element marshaller and detach their native pointers
+ for (; i < source.Length; i++)
+ {
+ destination[i] = TElementMarshaller.ConvertToUnmanaged(source[i]).DetachThisPtrUnsafe();
+ }
+ }
+ catch
+ {
+ // Make sure to release all marshalled objects so far (this shouldn't ever throw)
+ for (int j = 0; j < i; j++)
+ {
+ WindowsRuntimeUnknownMarshaller.Free(destination[j]);
+ }
+
+ // Also release the allocated array to avoid leaking
+ Marshal.FreeCoTaskMem((nint)destination);
+
+ throw;
+ }
+
+ size = (uint)source.Length;
+ array = destination;
+ }
+
+ ///
+ /// The type of marshaller for each managed array element.
+ public static T?[] ConvertToManaged(uint size, void** value)
+ where TElementMarshaller : IWindowsRuntimeReferenceTypeArrayElementMarshaller
+ {
+ if (size == 0)
+ {
+ return [];
+ }
+
+ ArgumentNullException.ThrowIfNull(value);
+
+ T?[] array = new T[(int)size];
+
+ for (int i = 0; i < size; i++)
+ {
+ array[i] = TElementMarshaller.ConvertToManaged(value[i]);
+ }
+
+ return array;
+ }
+
+ ///
+ /// The type of marshaller for each managed array element.
+ public static void CopyToUnmanaged(ReadOnlySpan source, uint size, void** destination)
+ where TElementMarshaller : IWindowsRuntimeReferenceTypeArrayElementMarshaller
+ {
+ WindowsRuntimeArrayMarshallerHelpers.ValidateDestinationSize(source.Length, size);
+
+ if (size == 0)
+ {
+ return;
+ }
+
+ ArgumentNullException.ThrowIfNull(destination);
+
+ int i = 0;
+
+ try
+ {
+ // Marshal the items in the input span
+ for (; i < source.Length; i++)
+ {
+ destination[i] = TElementMarshaller.ConvertToUnmanaged(source[i]).DetachThisPtrUnsafe();
+ }
+ }
+ catch
+ {
+ // Release resources for any items, if we failed
+ for (int j = 0; j < i; j++)
+ {
+ WindowsRuntimeUnknownMarshaller.Free(destination[j]);
+ }
+
+ throw;
+ }
+ }
+
+ ///
+ /// The type of marshaller for each managed array element.
+ public static void CopyToManaged(uint size, void** source, Span destination)
+ where TElementMarshaller : IWindowsRuntimeReferenceTypeArrayElementMarshaller
+ {
+ WindowsRuntimeArrayMarshallerHelpers.ValidateDestinationSize(size, destination.Length);
+
+ if (size == 0)
+ {
+ return;
+ }
+
+ ArgumentNullException.ThrowIfNull(source);
+
+ for (uint i = 0; i < size; i++)
+ {
+ destination[(int)i] = TElementMarshaller.ConvertToManaged(source[i]);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/WindowsRuntimeUnknownArrayMarshaller.cs b/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/WindowsRuntimeUnknownArrayMarshaller.cs
new file mode 100644
index 000000000..9ee3ecb2b
--- /dev/null
+++ b/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/WindowsRuntimeUnknownArrayMarshaller.cs
@@ -0,0 +1,39 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System;
+using System.ComponentModel;
+using System.Runtime.InteropServices;
+
+namespace WindowsRuntime.InteropServices.Marshalling;
+
+///
+/// A marshaller for arrays of some Windows Runtime types represented as unknown COM interfaces.
+///
+///
+/// This type mirrors , but for arrays.
+///
+[Obsolete(WindowsRuntimeConstants.PrivateImplementationDetailObsoleteMessage,
+ DiagnosticId = WindowsRuntimeConstants.PrivateImplementationDetailObsoleteDiagnosticId,
+ UrlFormat = WindowsRuntimeConstants.CsWinRTDiagnosticsUrlFormat)]
+[EditorBrowsable(EditorBrowsableState.Never)]
+public static unsafe class WindowsRuntimeUnknownArrayMarshaller
+{
+ ///
+ public static void Free(uint size, void** array)
+ {
+ if (size == 0)
+ {
+ return;
+ }
+
+ ArgumentNullException.ThrowIfNull(array);
+
+ for (uint i = 0; i < size; i++)
+ {
+ WindowsRuntimeUnknownMarshaller.Free(array[i]);
+ }
+
+ Marshal.FreeCoTaskMem((nint)array);
+ }
+}
\ No newline at end of file
diff --git a/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/WindowsRuntimeUnmanagedValueTypeArrayMarshaller{T, TAbi}.cs b/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/WindowsRuntimeUnmanagedValueTypeArrayMarshaller{T, TAbi}.cs
new file mode 100644
index 000000000..f4d623391
--- /dev/null
+++ b/src/WinRT.Runtime2/InteropServices/Marshalling/SzArrays/WindowsRuntimeUnmanagedValueTypeArrayMarshaller{T, TAbi}.cs
@@ -0,0 +1,135 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System;
+using System.ComponentModel;
+using System.Runtime.InteropServices;
+
+namespace WindowsRuntime.InteropServices.Marshalling;
+
+///
+/// A marshaller for arrays of unmanaged Windows Runtime types.
+///
+/// The type of elements in the array.
+/// The ABI type for type .
+[Obsolete(WindowsRuntimeConstants.PrivateImplementationDetailObsoleteMessage,
+ DiagnosticId = WindowsRuntimeConstants.PrivateImplementationDetailObsoleteDiagnosticId,
+ UrlFormat = WindowsRuntimeConstants.CsWinRTDiagnosticsUrlFormat)]
+[EditorBrowsable(EditorBrowsableState.Never)]
+public static unsafe class WindowsRuntimeUnmanagedValueTypeArrayMarshaller
+ where T : unmanaged
+ where TAbi : unmanaged
+{
+ ///
+ /// The type of marshaller for each managed array element.
+ public static void ConvertToUnmanaged(ReadOnlySpan source, out uint size, out TAbi* array)
+ where TElementMarshaller : IWindowsRuntimeUnmanagedValueTypeArrayElementMarshaller
+ {
+ if (source.IsEmpty)
+ {
+ size = 0;
+ array = null;
+
+ return;
+ }
+
+ TAbi* destination = (TAbi*)Marshal.AllocCoTaskMem(sizeof(T) * source.Length);
+
+ try
+ {
+ // Marshal all array elements with the provided element marshaller.
+ // We don't need to guard each call, as the ABI type is unmanaged.
+ for (int i = 0; i < source.Length; i++)
+ {
+ destination[i] = TElementMarshaller.ConvertToUnmanaged(source[i]);
+ }
+ }
+ catch
+ {
+ // If marshalling any element failed, release the allocated array to avoid
+ // leaking. This shouldn't really happen with unmanaged value type, since
+ // the conversions should be pretty trivial, but leave it just in case.
+ Marshal.FreeCoTaskMem((nint)destination);
+
+ throw;
+ }
+
+ size = (uint)source.Length;
+ array = destination;
+ }
+
+ ///
+ /// The type of marshaller for each managed array element.
+ public static T[] ConvertToManaged(uint size, TAbi* value)
+ where TElementMarshaller : IWindowsRuntimeUnmanagedValueTypeArrayElementMarshaller
+ {
+ if (size == 0)
+ {
+ return [];
+ }
+
+ ArgumentNullException.ThrowIfNull(value);
+
+ T[] array = GC.AllocateUninitializedArray((int)size);
+
+ for (int i = 0; i < size; i++)
+ {
+ array[i] = TElementMarshaller.ConvertToManaged(value[i]);
+ }
+
+ return array;
+ }
+
+ ///
+ /// The type of marshaller for each managed array element.
+ public static void CopyToUnmanaged(ReadOnlySpan source, uint size, TAbi* destination)
+ where TElementMarshaller : IWindowsRuntimeUnmanagedValueTypeArrayElementMarshaller
+ {
+ WindowsRuntimeArrayMarshallerHelpers.ValidateDestinationSize(source.Length, size);
+
+ if (size == 0)
+ {
+ return;
+ }
+
+ ArgumentNullException.ThrowIfNull(destination);
+
+ for (int i = 0; i < source.Length; i++)
+ {
+ destination[i] = TElementMarshaller.ConvertToUnmanaged(source[i]);
+ }
+ }
+
+ ///
+ /// The type of marshaller for each managed array element.
+ public static void CopyToManaged(uint size, TAbi* source, Span destination)
+ where TElementMarshaller : IWindowsRuntimeUnmanagedValueTypeArrayElementMarshaller
+ {
+ WindowsRuntimeArrayMarshallerHelpers.ValidateDestinationSize(size, destination.Length);
+
+ if (size == 0)
+ {
+ return;
+ }
+
+ ArgumentNullException.ThrowIfNull(source);
+
+ for (uint i = 0; i < size; i++)
+ {
+ destination[(int)i] = TElementMarshaller.ConvertToManaged(source[i]);
+ }
+ }
+
+ ///
+ public static void Free(uint size, TAbi* array)
+ {
+ if (size == 0)
+ {
+ return;
+ }
+
+ ArgumentNullException.ThrowIfNull(array);
+
+ Marshal.FreeCoTaskMem((nint)array);
+ }
+}
\ No newline at end of file
diff --git a/src/WinRT.Runtime2/InteropServices/Marshalling/WindowsRuntimeObjectMarshaller.cs b/src/WinRT.Runtime2/InteropServices/Marshalling/WindowsRuntimeObjectMarshaller.cs
index ac9be8284..08c8b115a 100644
--- a/src/WinRT.Runtime2/InteropServices/Marshalling/WindowsRuntimeObjectMarshaller.cs
+++ b/src/WinRT.Runtime2/InteropServices/Marshalling/WindowsRuntimeObjectMarshaller.cs
@@ -72,7 +72,7 @@ static void ThrowNotSupportedException(object value)
/// Converts an unmanaged pointer to a Windows Runtime object to a managed object.
///
/// The input object to convert to managed.
- /// The resulting managed managed object.
+ /// The resulting managed object.
public static object? ConvertToManaged(void* value)
{
if (value is null)