Skip to content

Conversation

@haolink
Copy link
Contributor

@haolink haolink commented Sep 1, 2025

This is a fix proposal for #210 - I was trying to work with Neptunia Sisters Vs Sisters which is affected by the same issue the user reported there.

When the mono object is a System.Action object it seems GetGcHandlePtrFromIl2CppObject(pointer) returns a null pointer for the Garbage Collector Handle (or well IntPtr.Zero). This causes GCHandle.FromIntPtr(gcHandle) to throw an excepction.

One solution after a lot of back and forth was to essentially check if the object class is a Delegate type class (which includes System.Action) and if so, get the garbage collector handle on the mTarget of the delegate object. This way in my testing the code will not interfere with other Unity versions - yet it allows to hook onto my test game - which happens to be a 2021.2.x game compiled with IL2CPP.

In other Unity versions if (gcHandle == IntPtr.Zero) should be false so I doubt this would interfere in any way (it worked fine in other tested games for me).

@soqb
Copy link

soqb commented Sep 1, 2025

i wonder if #216 also fixes this issue. it totally elides GetGcHandlePtrFromIl2CppObject.

@haolink
Copy link
Contributor Author

haolink commented Sep 2, 2025

I tried using the improved-gc branch testwise - used Common.dll, HarmonySupport.dll and Runtime.dll from that one (If I need other ones, please yell at me) and currently the game crashed. The log is attached.

Ultimate error is: [Error :Il2CppInterop] Field MethodInfo was not found on class LogCallback

I didn't have much time to look into this now, I will try to see using your branch if I can get it to work. My best guess is that bodyBuilder.Emit(OpCodes.Ldfld, typeof(Il2CppToMonoDelegateReference).GetField(nameof(Il2CppToMonoDelegateReference.MethodInfo))); in DelegateSupport.cs (which is the method which I used to have a lot of tracing enabled during my testing) is failing. I'll look into it after work today.

Thank you for looking.

LogOutput.log

Copy link
Member

@ManlyMarco ManlyMarco left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a hack but it seems to be working well, merging for v1.5.1.
This code will be replaced in v2.0 with a proper fix.

@ManlyMarco ManlyMarco merged commit f39ea5a into BepInEx:master Sep 2, 2025
2 checks passed
@ds5678 ds5678 added this to the 1.5.1 milestone Sep 2, 2025
XtraCube pushed a commit to XtraCube/Il2CppInterop that referenced this pull request Sep 18, 2025
When the mono object is a System.Action object it seems GetGcHandlePtrFromIl2CppObject(pointer) returns a null pointer for the Garbage Collector Handle (or well IntPtr.Zero). This causes GCHandle.FromIntPtr(gcHandle) to throw an excepction.

One solution after a lot of back and forth was to essentially check if the object class is a Delegate type class (which includes System.Action) and if so, get the garbage collector handle on the mTarget of the delegate object. This way in my testing the code will not interfere with other Unity versions - yet it allows to hook onto my test game - which happens to be a 2021.2.x game compiled with IL2CPP.

In other Unity versions if (gcHandle == IntPtr.Zero) should be false so I doubt this would interfere in any way (it worked fine in other tested games for me).

----

It's a hack but it seems to be working well, merging for v1.5.1. This code will be replaced in v2.0 with a proper fix.

(cherry picked from commit f39ea5a)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants