diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/MarshallingGenerator.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/MarshallingGenerator.cs
index 2f622da69344d5..3c8e6c09aa3581 100644
--- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/MarshallingGenerator.cs
+++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/MarshallingGenerator.cs
@@ -30,10 +30,12 @@ public enum SignatureBehavior
/// The native type should match the managed type, including rehydrating marshalling attributes and by-ref syntax (pure forwarding).
///
ManagedTypeAndAttributes,
+
///
/// The native signature should be the type returned by passed by value.
///
NativeType,
+
///
/// The native signature should be a pointer to the type returned by passed by value.
///
@@ -49,14 +51,21 @@ public enum ValueBoundaryBehavior
/// The managed value should be passed as-is, including any managed by-ref syntax used in the managed declaration.
///
ManagedIdentifier,
+
///
/// The native identifier provided by should be passed by value.
///
NativeIdentifier,
+
///
/// The address of the native identifier provided by should be passed by value.
///
- AddressOfNativeIdentifier
+ AddressOfNativeIdentifier,
+
+ ///
+ /// The native identifier provided by should be cast to the native type.
+ ///
+ CastNativeIdentifier
}
///
diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/MarshallingGeneratorExtensions.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/MarshallingGeneratorExtensions.cs
index 8de5682ac01580..e07e8baaf616b0 100644
--- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/MarshallingGeneratorExtensions.cs
+++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/MarshallingGeneratorExtensions.cs
@@ -96,7 +96,6 @@ private static ParameterSyntax GenerateForwardingParameter(TypePositionInfo info
return param;
}
-
private static bool TryRehydrateMarshalAsAttribute(TypePositionInfo info, out AttributeSyntax marshalAsAttribute)
{
marshalAsAttribute = null!;
@@ -203,6 +202,7 @@ public static ArgumentSyntax AsArgument(this IMarshallingGenerator generator, Ty
ValueBoundaryBehavior.ManagedIdentifier when info.IsByRef => Argument(IdentifierName(managedIdentifier)).WithRefKindKeyword(Token(info.RefKindSyntax)),
ValueBoundaryBehavior.NativeIdentifier => Argument(IdentifierName(nativeIdentifier)),
ValueBoundaryBehavior.AddressOfNativeIdentifier => Argument(PrefixUnaryExpression(SyntaxKind.AddressOfExpression, IdentifierName(nativeIdentifier))),
+ ValueBoundaryBehavior.CastNativeIdentifier => Argument(CastExpression(generator.AsParameter(info).Type, IdentifierName(nativeIdentifier))),
_ => throw new InvalidOperationException()
};
}
diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/PinnableManagedValueMarshaller.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/PinnableManagedValueMarshaller.cs
index 191713bbf019f4..3531a8cc8d0e6c 100644
--- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/PinnableManagedValueMarshaller.cs
+++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/PinnableManagedValueMarshaller.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
+using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
@@ -25,8 +26,17 @@ public ValueBoundaryBehavior GetValueBoundaryBehavior(TypePositionInfo info, Stu
{
if (IsPinningPathSupported(info, context))
{
- return ValueBoundaryBehavior.NativeIdentifier;
+ if (AsNativeType(info) is PointerTypeSyntax pointerType
+ && pointerType.ElementType is PredefinedTypeSyntax predefinedType
+ && predefinedType.Keyword.IsKind(SyntaxKind.VoidKeyword))
+ {
+ return ValueBoundaryBehavior.NativeIdentifier;
+ }
+
+ // Cast to native type if it is not void*
+ return ValueBoundaryBehavior.CastNativeIdentifier;
}
+
return _innerMarshallingGenerator.GetValueBoundaryBehavior(info, context);
}
@@ -46,6 +56,7 @@ public IEnumerable Generate(TypePositionInfo info, StubCodeCont
{
return GeneratePinningPath(info, context);
}
+
return _innerMarshallingGenerator.Generate(info, context);
}
@@ -60,6 +71,7 @@ public bool UsesNativeIdentifier(TypePositionInfo info, StubCodeContext context)
{
return false;
}
+
return _innerMarshallingGenerator.UsesNativeIdentifier(info, context);
}
private static bool IsPinningPathSupported(TypePositionInfo info, StubCodeContext context)
@@ -67,32 +79,24 @@ private static bool IsPinningPathSupported(TypePositionInfo info, StubCodeContex
return context.SingleFrameSpansNativeContext && !info.IsByRef && !info.IsManagedReturnPosition;
}
- private IEnumerable GeneratePinningPath(TypePositionInfo info, StubCodeContext context)
+ private static IEnumerable GeneratePinningPath(TypePositionInfo info, StubCodeContext context)
{
if (context.CurrentStage == StubCodeContext.Stage.Pin)
{
(string managedIdentifier, string nativeIdentifier) = context.GetIdentifiers(info);
- string pinnedIdentifier = context.GetAdditionalIdentifier(info, "pinned");
+
+ // fixed (void* = )
yield return FixedStatement(
VariableDeclaration(
PointerType(PredefinedType(Token(SyntaxKind.VoidKeyword))),
SingletonSeparatedList(
- VariableDeclarator(Identifier(pinnedIdentifier))
+ VariableDeclarator(Identifier(nativeIdentifier))
.WithInitializer(EqualsValueClause(
IdentifierName(managedIdentifier)
))
)
),
- // = ();
- LocalDeclarationStatement(
- VariableDeclaration(AsNativeType(info),
- SingletonSeparatedList(
- VariableDeclarator(nativeIdentifier)
- .WithInitializer(EqualsValueClause(
- CastExpression(
- AsNativeType(info),
- IdentifierName(pinnedIdentifier)))))))
- );
+ EmptyStatement());
}
}
}