Keep `this` alive across the native call for VTable-based source-generation (#85723)
authorJeremy Koritzinsky <jekoritz@microsoft.com>
Thu, 4 May 2023 12:54:08 +0000 (05:54 -0700)
committerGitHub <noreply@github.com>
Thu, 4 May 2023 12:54:08 +0000 (14:54 +0200)
* Keep `this` alive across the native call for VTable-based source-generation

src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ManagedToNativeVTableMethodGenerator.cs
src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/TypeNames.cs

index 482cc2b..3792231 100644 (file)
@@ -185,6 +185,19 @@ namespace Microsoft.Interop
             }
 
             tryStatements.AddRange(statements.NotifyForSuccessfulInvoke);
+
+            // Keep the this object alive across the native call, similar to how we handle marshalling managed delegates.
+            // We do this right after the NotifyForSuccessfulInvoke phase as that phase is where the delegate objects are kept alive.
+            // If we ever move the "this" object handling out of this type, we'll move the handling to be emitted in that phase.
+            // GC.KeepAlive(this);
+            tryStatements.Add(
+                ExpressionStatement(
+                    InvocationExpression(
+                        MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
+                            ParseTypeName(TypeNames.System_GC),
+                            IdentifierName("KeepAlive")),
+                        ArgumentList(SingletonSeparatedList(Argument(ThisExpression()))))));
+
             tryStatements.AddRange(statements.Unmarshal);
 
             List<StatementSyntax> allStatements = setupStatements;
index 43a458a..314b819 100644 (file)
@@ -51,6 +51,8 @@ namespace Microsoft.Interop
 
         public const string System_Exception = "System.Exception";
 
+        public const string System_GC = "System.GC";
+
         public const string System_Type = "System.Type";
 
         public const string System_Int16 = "System.Int16";