[C#] Use an instance of the callback delegate, not the fn itself
authorMatt Corallo <git@bluematt.me>
Tue, 23 Jan 2024 21:19:51 +0000 (21:19 +0000)
committerMatt Corallo <git@bluematt.me>
Mon, 29 Jan 2024 16:37:41 +0000 (16:37 +0000)
When passing the callback delegate to C from C# during static init,
it appears (but only on Windows) this actually creates a C# class
instance for the delegate and passes that. However, that class
instance is eventually GC'd and our callbacks will start failing.

Instead, we create a static instance of of the delegate and pass
that to C.

csharp_strings.py

index 9dd23d1f9f4c0e8b2c8541fa96a88f710b24b066..c1873f3d8aefdd1a1f584db301d80d725875de72 100644 (file)
@@ -1442,10 +1442,11 @@ public class {struct_name.replace("LDK","")} : CommonBase {{
                }}
        }}
        public delegate {jret} {fn_suffix}_callback(int obj_ptr, int fn_id{jargs});
+       static {fn_suffix}_callback {fn_suffix}_callback_inst = c_callback_{fn_suffix};
 """)
                 bindings.write(self.native_meth_decl(f"register_{fn_suffix}_invoker", "int") + f"({fn_suffix}_callback callee);\n")
                 # Easiest way to get a static run is just define a variable, even if we dont care
-                bindings.write(f"\tstatic int _run_{fn_suffix}_registration = register_{fn_suffix}_invoker(c_callback_{fn_suffix});")
+                bindings.write(f"\tstatic int _run_{fn_suffix}_registration = register_{fn_suffix}_invoker({fn_suffix}_callback_inst);")
 
             bindings.write("""
 }