MonoPInvokeCallbackAnalyzer.cs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. using dnlib.DotNet;
  2. using HybridCLR.Editor.ABI;
  3. using HybridCLR.Editor.Meta;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using CallingConvention = System.Runtime.InteropServices.CallingConvention;
  10. using UnityEngine;
  11. namespace HybridCLR.Editor.MethodBridge
  12. {
  13. public class RawMonoPInvokeCallbackMethodInfo
  14. {
  15. public MethodDef Method { get; set; }
  16. public CustomAttribute GenerationAttribute { get; set; }
  17. }
  18. public class MonoPInvokeCallbackAnalyzer
  19. {
  20. private readonly List<ModuleDefMD> _rootModules = new List<ModuleDefMD>();
  21. private readonly List<RawMonoPInvokeCallbackMethodInfo> _reversePInvokeMethods = new List<RawMonoPInvokeCallbackMethodInfo>();
  22. public List<RawMonoPInvokeCallbackMethodInfo> ReversePInvokeMethods => _reversePInvokeMethods;
  23. public MonoPInvokeCallbackAnalyzer(AssemblyCache cache, List<string> assemblyNames)
  24. {
  25. foreach (var assemblyName in assemblyNames)
  26. {
  27. _rootModules.Add(cache.LoadModule(assemblyName));
  28. }
  29. }
  30. private void CollectReversePInvokeMethods()
  31. {
  32. foreach (var mod in _rootModules)
  33. {
  34. Debug.Log($"ass:{mod.FullName} method count:{mod.Metadata.TablesStream.MethodTable.Rows}");
  35. for (uint rid = 1, n = mod.Metadata.TablesStream.MethodTable.Rows; rid <= n; rid++)
  36. {
  37. var method = mod.ResolveMethod(rid);
  38. //Debug.Log($"method:{method}");
  39. if (!method.IsStatic || !method.HasCustomAttributes)
  40. {
  41. continue;
  42. }
  43. CustomAttribute wa = method.CustomAttributes.FirstOrDefault(ca => ca.AttributeType.Name == "MonoPInvokeCallbackAttribute");
  44. if (wa == null)
  45. {
  46. continue;
  47. }
  48. if (!MetaUtil.IsSupportedPInvokeMethodSignature(method.MethodSig))
  49. {
  50. Debug.LogError($"MonoPInvokeCallback method {method.FullName} has unsupported parameter or return type. Please check the method signature.");
  51. }
  52. //foreach (var ca in method.CustomAttributes)
  53. //{
  54. // Debug.Log($"{ca.AttributeType.FullName} {ca.TypeFullName}");
  55. //}
  56. _reversePInvokeMethods.Add(new RawMonoPInvokeCallbackMethodInfo()
  57. {
  58. Method = method,
  59. GenerationAttribute = method.CustomAttributes.FirstOrDefault(ca => ca.AttributeType.FullName == "HybridCLR.ReversePInvokeWrapperGenerationAttribute"),
  60. });
  61. }
  62. }
  63. }
  64. public void Run()
  65. {
  66. CollectReversePInvokeMethods();
  67. }
  68. }
  69. }