Generator.cs 2.4 KB

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