From 52329a425adbefe5776a2fb01b516d31634518d8 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Tue, 23 Jan 2024 21:19:51 +0000 Subject: [PATCH] [C#] Use an instance of the callback delegate, not the fn itself 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 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/csharp_strings.py b/csharp_strings.py index 9dd23d1f..c1873f3d 100644 --- a/csharp_strings.py +++ b/csharp_strings.py @@ -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(""" } -- 2.30.2