[Bug]: IL2CPP. Patching a property's Setter and Getter. NullReferenceException.
Eugenii10 opened this issue ยท 4 comments
All of the following criteria must be met
- All Requirements must be installed.
- Full
Latest.log
file included. If no file exists then leave this unchecked and state so.
All of the following are optional to answer
- Tried reinstalling the Game.
- Tried reinstalling MelonLoader.
- Tried restarting PC.
- Was able to see the Start Screen.
Describe the issue.
Is patching property's Setter and Getter methods working correctly with IL2CPP games (modern Unity 2019+)?
When I try to do this, I got an NullReferenceException error:
[17:17:06.139] [Gameplay_Extensions] [ERROR] System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> HarmonyLib.HarmonyException: Patching exception in method void Mdl.Graphic.DayAndNight::set_seconds(float ) ---> System.NullReferenceException: Object reference not set to an instance of an object
at UnhollowerBaseLib.Runtime.VersionSpecific.MethodInfo.NativeMethodInfoStructHandler_24_1.CopyMethodInfoStruct (System.IntPtr origMethodInfo) [0x0000e] in <6f5e4ff5bbd94258ab8bd773251f8e6c>:0
I have tried MelonLoader 0.5.4 and latest 0.6.0. The attached log is from 0.6.0 despite the version reported in the log.
However it is working with a readonly Property (with Getter only).
I assume that the problem can be in the Il2CppAssemblyUnhollower.
The two properties IL code slightly differs in generated managed assemblies.
ReadOnly property's C# code:
using System;
using System.Runtime.CompilerServices;
using UnhollowerBaseLib;
using UnhollowerBaseLib.Attributes;
public unsafe float minuteProgress
{
[CallerCount(0)]
get
{
IL2CPP.Il2CppObjectBaseToPtrNotNull(this);
IntPtr* param = null;
System.Runtime.CompilerServices.Unsafe.SkipInit(out IntPtr exc);
IntPtr obj = IL2CPP.il2cpp_runtime_invoke(NativeMethodInfoPtr_get_minuteProgress_Private_get_Single_0, IL2CPP.Il2CppObjectBaseToPtrNotNull(this), (void**)param, ref exc);
Il2CppException.RaiseExceptionIfNecessary(exc);
return *(float*)IL2CPP.il2cpp_object_unbox(obj);
}
}
Full access property's C# code:
using UnhollowerBaseLib;
public unsafe float seconds
{
get
{
nint num = (nint)IL2CPP.Il2CppObjectBaseToPtrNotNull(this) + (int)IL2CPP.il2cpp_field_get_offset(NativeFieldInfoPtr_seconds);
return *(float*)num;
}
set
{
*(float*)((nint)IL2CPP.Il2CppObjectBaseToPtrNotNull(this) + (int)IL2CPP.il2cpp_field_get_offset(NativeFieldInfoPtr_seconds)) = value;
}
}
Did you attach your log file?
- Yes, I attached my log file to the text box above.
- No, I could not find a log file at
{Game_Directory}\MelonLoader\Latest.log
Unhollower implements fields as properties for reasons that should be obvious - you can't call methods from field getters.
So is it not how IL2CPP compiled game works inside? Are there no "pseudo" properties for these fields? Then it is reasonable that it couldn't patched non-existing "method".
It is strange that sometimes ILSpy displays Setter and Getter methods for such "properties" in the tree, and sometimes it doesn't. Maybe it is connected with the difference in how assemblies are generated by the Unhollower for these games.
So is it not how IL2CPP compiled game works inside?
Correct
Are there no "pseudo" properties for these fields?
No.
It is strange that sometimes ILSpy displays Setter and Getter methods for such "properties" in the tree, and sometimes it doesn't.
This sounds more like an ILSpy bug, both of those clearly have il2cpp_field_get_offset calls and so are fields.
That would be because those aren't properties, they're fields - as you can see by the call to il2cpp_field_get_offset in the "property" accessors. Unhollower implements fields as properties for reasons that should be obvious - you can't call methods from field getters.