beatsaber-hook
beatsaber-hook copied to clipboard
MakeGenericMethod
Unity Version: 2021.3.16f1 (4016570cf34f)
In this version 2021.3.16f1, struct Il2CppDefaults
dosen't have mono_method_class
property, so I can't get mono_method_class
in file typedefs.h
here is the relevant code:
DEFINE_IL2CPP_DEFAULT_TYPE(Il2CppReflectionMethod*, mono_method);
In il2cpp_utils::MakeGenericMethod()
method, it calls the MakeGenericMethod
method in Il2CppClass mono_method_calss
:
auto res = il2cpp_utils::RunMethod<Il2CppReflectionMethod*, false>(infoObj, "MakeGenericMethod", arr);
So, how should I make a method from generic method in this version?
// C#
// Invoke the method get from generic method
System.Reflection.MethodInfo mi = typeof(Component).GetMethod("GetComponent", System.Type.EmptyTypes);
System.Reflection.MethodInfo miConstructed = mi.MakeGenericMethod(typeof(Rigidbody));
Rigidbody rigidbody = (Rigidbody)miConstructed.Invoke(this, null);
// Invoke the method normally.
Rigidbody rigidbody = GetComponent<Rigidbody>();
Apologies for only catching up to this now (literally 5 months after you posted this...) Unity 2021 is not yet supported. As for making generic methods, I'd need to do a bit of looking to see how they get forwarded on latest, but the current approach is already a hack over a hack-- we could stand to replace it with more correct behavior, where we inflate the metadata directly to make a MethodInfo*
that we can use for invokes.
Really, we don't even need a MethodInfo*
, we could just use the AOT generated method pointers directly. I'll leave this open for now and when unity 2021 support lands, I'll update this.
Based on your code, with some modifications, it is now functioning correctly.
I examined the code in the il2cpp-object-internals.h
file in the libil2cpp
folder of Unity. There is a definition for Il2CppReflectionMethod
:
// System.Reflection.MonoMethod
typedef struct Il2CppReflectionMethod
{
Il2CppObject object;
const MethodInfo *method;
Il2CppString *name;
Il2CppReflectionType *reftype;
} Il2CppReflectionMethod;
In C#, System.Reflection.MonoMethod
inherits from RuntimeMethodInfo
. I found the definition of the MakeGenericMethod
method in RuntimeMethodInfo
here.
Therefore, I replaced mono_method_class
with System.Reflection.RuntimeMethodInfo
:
Il2CppClass *method_class = il2cpp_class_from_name(il2cpp_defaults.corlib, "System.Reflection", "RuntimeMethodInfo");
const MethodInfo *method_MakeGenericMethod = il2cpp_class_get_method_from_name(method_class, "MakeGenericMethod", 1);
That's all.