public static void Gen() { using (new CS(IcallWriter)) { CS.Writer.WriteLine("#include \"engine_include.h\"", false); CS.Writer.WriteLine("#include \"class_cache_gen.h\"", false); RegisterAssemblyMap(); foreach (var m in methodSet) { CS.Writer.Start($"{CTypeResolver.Resolve(m.ReturnType).TypeName()} {CUtils.ImplementMethodName(m, true)}"); ImplementBindMethod(m); CS.Writer.End(); } CS.Writer.Start("void regist_icall_gen()"); foreach (var m in methodSet) { CS.Writer.WriteLine($"mono_add_internal_call(\"{CUtils.GetICallDescName(m)}\",(void*) {CUtils.ImplementMethodName(m, false)})"); } CS.Writer.End(); } IcallWriter.EndAll(); }
public static void Gen() { using (new CS(EventWriter)) { CS.Writer.WriteLine("#include \"event_binding.h\"", false); CS.Writer.WriteLine("#include \"class_cache_gen.h\"", false); CS.Writer.WriteLine($"EventMethodDesc methods[{methodSet.Count}]"); int index = 0; foreach (var m in methodSet) { CS.Writer.Start($"{CTypeResolver.Resolve(m.ReturnType,true).TypeName()} {CUtils.ImplementMethodName(m, false) + CUtils.GetParamDefine(m, true, "const MethodInfo* imethod")} "); ImplementEventMethod(m, index); CS.Writer.End(); index++; } index = 0; CS.Writer.Start("void init_event_gen()"); foreach (var m in methodSet) { CS.Writer.WriteLine($"init_event_method(&methods[{index}],{ClassCacheGenerater.GetClass(m.DeclaringType,false)},{ClassCacheGenerater.GetClass(m.DeclaringType, true)}," + $"\"{m.Name}\",{m.Parameters.Count},(Il2CppMethodPointer) {CUtils.ImplementMethodName(m, false)})"); index++; } CS.Writer.End(); } EventWriter.EndAll(); }
private static void ImplementBindMethod(MethodDefinition method) { var i2ReturnTypeName = CTypeResolver.Resolve(method.ReturnType, true).TypeName(); CS.Writer.WriteLine($"typedef {i2ReturnTypeName} (* ICallMethod) {CUtils.GetParamDefine(method, true)}"); CS.Writer.WriteLine("static ICallMethod icall"); CS.Writer.WriteLine("if(!icall)", false); CS.Writer.WriteLine("\t" + $"icall = (ICallMethod)il2cpp_resolve_icall(\"{CUtils.GetICallDescName(method)}\")"); if (method.ReturnType.IsVoid()) { CS.Writer.WriteLine("icall(", false); } else { CS.Writer.WriteLine($"{i2ReturnTypeName} i2res = icall(", false); } if (!method.IsStatic) { CS.Writer.Write(CTypeResolver.Resolve(method.DeclaringType).Unbox("thiz", true)); if (method.Parameters.Count > 0) { CS.Writer.Write(","); } } var lastP = method.Parameters.LastOrDefault(); foreach (var p in method.Parameters) { CS.Writer.Write(CTypeResolver.Resolve(p.ParameterType).Unbox(p.Name, true)); if (lastP != p) { CS.Writer.Write(","); } } CS.Writer.Write(");"); if (!method.ReturnType.IsVoid()) { var monoRes = CTypeResolver.Resolve(method.ReturnType).Box("i2res"); CS.Writer.WriteLine($"return {monoRes}"); } }
/* * void UnityEngine_AsyncOperation_InvokeCompletionEvent(Il2CppObject* obj, const MethodInfo* imethod) * { * const int index = 52; * typedef void(*THUNK_METHOD EventMethod) (MonoObject* obj, MonoException** exc); * static EventMethod thunk; * if (!thunk) * thunk = mono_method_get_unmanaged_thunk(methods[index].hooked); * MonoException *exc = NULL; * MonoObject* monoobj = get_mono_object(obj, mono_get_class_UnityEngine_AsyncOperation()); * thunk(monoobj, &exc); * } */ private static void ImplementEventMethod(MethodDefinition method, int index) { var returnTypeName = CTypeResolver.Resolve(method.ReturnType, false).TypeName(); CS.Writer.WriteLine($"const int index = {index}"); CS.Writer.WriteLine($"typedef {returnTypeName} (* THUNK_METHOD EventMethod) {CUtils.GetParamDefine(method, false, "MonoException** exc")}"); CS.Writer.WriteLine("static EventMethod thunk"); CS.Writer.WriteLine("if(!thunk)", false); CS.Writer.WriteLine("\t" + $"thunk = mono_method_get_unmanaged_thunk(methods[index].hooked)"); CS.Writer.WriteLine("MonoException *exc = NULL"); if (method.ReturnType.IsVoid()) { CS.Writer.WriteLine("thunk(", false); } else { CS.Writer.WriteLine($"{returnTypeName} res = thunk(", false); } if (!method.IsStatic) { CS.Writer.Write(CTypeResolver.Resolve(method.DeclaringType).Box("thiz", true)); //if (method.Parameters.Count > 0) CS.Writer.Write(","); } var lastP = method.Parameters.LastOrDefault(); foreach (var p in method.Parameters) { CS.Writer.Write(CTypeResolver.Resolve(p.ParameterType).Box(p.Name, true)); //if (lastP != p) CS.Writer.Write(","); } CS.Writer.Write("&exc);"); CS.Writer.WriteLine("check_mono_exception(exc)"); if (!method.ReturnType.IsVoid()) { var monoRes = CTypeResolver.Resolve(method.ReturnType).Unbox("res", false); CS.Writer.WriteLine($"return {monoRes}"); } }
public static string GetParamDefine(MethodDefinition method, bool il2cpp, string addParam = null) { var param = "("; if (!method.IsStatic) { if (il2cpp) { param += "Il2CppObject* thiz"; } else { param += "MonoObject* thiz"; } if (method.HasParameters) { param += ", "; } } var lastP = method.Parameters.LastOrDefault(); foreach (var p in method.Parameters) { param += CTypeResolver.Resolve(p.ParameterType, il2cpp).Paramer(p.Name) + (p == lastP ? "" : ", "); } if (addParam != null) { if (!param.EndsWith("(") && !param.EndsWith(", ")) { param += ", "; } param += addParam; } param += ")"; return(param); }