Generator.cs 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. using HybridCLR.Editor.ABI;
  2. using HybridCLR.Editor.Template;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. using System.Linq;
  7. using System.Text;
  8. using UnityEngine;
  9. namespace HybridCLR.Editor.ReversePInvokeWrap
  10. {
  11. public class Generator
  12. {
  13. public void Generate(List<ABIReversePInvokeMethodInfo> methods, string outputFile)
  14. {
  15. string template = File.ReadAllText(outputFile, Encoding.UTF8);
  16. var frr = new FileRegionReplace(template);
  17. var codes = new List<string>();
  18. int methodIndex = 0;
  19. var stubCodes = new List<string>();
  20. foreach(var methodInfo in methods)
  21. {
  22. MethodDesc method = methodInfo.Method;
  23. string paramDeclaringListWithoutMethodInfoStr = string.Join(", ", method.ParamInfos.Select(p => $"{p.Type.GetTypeName()} __arg{p.Index}"));
  24. string paramNameListWithoutMethodInfoStr = string.Join(", ", method.ParamInfos.Select(p => $"__arg{p.Index}").Concat(new string[] { "method" }));
  25. string paramTypeListWithMethodInfoStr = string.Join(", ", method.ParamInfos.Select(p => $"{p.Type.GetTypeName()}").Concat(new string[] { "const MethodInfo*" }));
  26. string methodTypeDef = $"typedef {method.ReturnInfo.Type.GetTypeName()} (*Callback)({paramTypeListWithMethodInfoStr})";
  27. for (int i = 0; i < methodInfo.Count; i++, methodIndex++)
  28. {
  29. codes.Add($@"
  30. {method.ReturnInfo.Type.GetTypeName()} __ReversePInvokeMethod_{methodIndex}({paramDeclaringListWithoutMethodInfoStr})
  31. {{
  32. const MethodInfo* method = MetadataModule::GetMethodInfoByReversePInvokeWrapperIndex({methodIndex});
  33. {methodTypeDef};
  34. {(method.ReturnInfo.IsVoid ? "" : "return ")}((Callback)(method->methodPointerCallByInterp))({paramNameListWithoutMethodInfoStr});
  35. }}
  36. ");
  37. stubCodes.Add($"\t\t{{\"{method.Sig}\", (Il2CppMethodPointer)__ReversePInvokeMethod_{methodIndex}}},\n");
  38. }
  39. Debug.Log($"[ReversePInvokeWrap.Generator] method:{method.MethodDef} wrapperCount:{methodInfo.Count}");
  40. }
  41. codes.Add(@"
  42. ReversePInvokeMethodData g_reversePInvokeMethodStub[]
  43. {
  44. ");
  45. codes.AddRange(stubCodes);
  46. codes.Add(@"
  47. {nullptr, nullptr},
  48. };
  49. ");
  50. frr.Replace("CODE", string.Join("", codes));
  51. frr.Commit(outputFile);
  52. }
  53. }
  54. }