Skip to content

Fix "Handle is not initialized" for Unity 2021.2.x games#232

Merged
ManlyMarco merged 3 commits into
BepInEx:masterfrom
haolink:master
Sep 2, 2025
Merged

Fix "Handle is not initialized" for Unity 2021.2.x games#232
ManlyMarco merged 3 commits into
BepInEx:masterfrom
haolink:master

Conversation

@haolink

@haolink haolink commented Sep 1, 2025

Copy link
Copy Markdown
Contributor

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

soqb commented Sep 1, 2025

Copy link
Copy Markdown

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

@haolink

haolink commented Sep 2, 2025

Copy link
Copy Markdown
Contributor Author

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

@ManlyMarco ManlyMarco left a comment

Copy link
Copy Markdown
Member

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.

Comment thread Il2CppInterop.Runtime/Runtime/ClassInjectorBase.cs Outdated
@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 All-Of-Us-Mods/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)
sptndc pushed a commit to sptndc/Il2CppInterop that referenced this pull request Jun 24, 2026
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.
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