| File: Marshalling\StaticPinnableManagedValueMarshaller.cs | Web Access |
| Project: Microsoft.Interop.SourceGeneration.csproj (Microsoft.Interop.SourceGeneration) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. namespace Microsoft.Interop { public sealed class StaticPinnableManagedValueMarshaller(IBoundMarshallingGenerator innerMarshallingGenerator, string getPinnableReferenceType) : IBoundMarshallingGenerator { public TypePositionInfo TypeInfo => innerMarshallingGenerator.TypeInfo; public StubCodeContext CodeContext => innerMarshallingGenerator.CodeContext; public ManagedTypeInfo NativeType => innerMarshallingGenerator.NativeType; public SignatureBehavior NativeSignatureBehavior => innerMarshallingGenerator.NativeSignatureBehavior; public ValueBoundaryBehavior ValueBoundaryBehavior { get { if (IsPinningPathSupported(CodeContext)) { if (NativeType is PointerTypeInfo { IsFunctionPointer: false, FullTypeName: "void*" }) { return Interop.ValueBoundaryBehavior.NativeIdentifier; } // Cast to native type if it is not void* return Interop.ValueBoundaryBehavior.CastNativeIdentifier; } return innerMarshallingGenerator.ValueBoundaryBehavior; } } public void Generate(IndentedTextWriter writer, StubIdentifierContext context) { if (IsPinningPathSupported(CodeContext)) { GeneratePinningPath(writer, context); return; } innerMarshallingGenerator.Generate(writer, context); } public bool UsesNativeIdentifier { get { if (IsPinningPathSupported(CodeContext)) { return false; } return innerMarshallingGenerator.UsesNativeIdentifier; } } private bool IsPinningPathSupported(StubCodeContext context) { return context.SingleFrameSpansNativeContext && !TypeInfo.IsByRef && !context.IsInStubReturnPosition(TypeInfo); } private void GeneratePinningPath(IndentedTextWriter writer, StubIdentifierContext context) { if (context.CurrentStage == StubIdentifierContext.Stage.Pin) { (string managedIdentifier, string nativeIdentifier) = context.GetIdentifiers(innerMarshallingGenerator.TypeInfo); writer.WriteLine($"fixed (void* {nativeIdentifier} = &{getPinnableReferenceType}.{ShapeMemberNames.GetPinnableReference}({managedIdentifier}))"); } } public ByValueMarshalKindSupport SupportsByValueMarshalKind(ByValueContentsMarshalKind marshalKind, out GeneratorDiagnostic? diagnostic) { return innerMarshallingGenerator.SupportsByValueMarshalKind(marshalKind, out diagnostic); } } }