PInvokeAnalyzer.cs 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. using dnlib.DotNet;
  2. using HybridCLR.Editor.Meta;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Runtime.CompilerServices;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using UnityEngine;
  10. namespace HybridCLR.Editor.MethodBridge
  11. {
  12. public class PInvokeAnalyzer
  13. {
  14. private readonly List<ModuleDefMD> _rootModules = new List<ModuleDefMD>();
  15. private readonly List<CallNativeMethodSignatureInfo> _pinvokeMethodSignatures = new List<CallNativeMethodSignatureInfo>();
  16. public List<CallNativeMethodSignatureInfo> PInvokeMethodSignatures => _pinvokeMethodSignatures;
  17. public PInvokeAnalyzer(AssemblyCache cache, List<string> assemblyNames)
  18. {
  19. foreach (var assemblyName in assemblyNames)
  20. {
  21. _rootModules.Add(cache.LoadModule(assemblyName));
  22. }
  23. }
  24. private CallingConvention GetCallingConvention(MethodDef method)
  25. {
  26. switch (method.ImplMap.CallConv)
  27. {
  28. case PInvokeAttributes.CallConvWinapi: return CallingConvention.Default;
  29. case PInvokeAttributes.CallConvCdecl: return CallingConvention.C;
  30. case PInvokeAttributes.CallConvStdCall: return CallingConvention.StdCall;
  31. case PInvokeAttributes.CallConvThiscall: return CallingConvention.ThisCall;
  32. case PInvokeAttributes.CallConvFastcall: return CallingConvention.FastCall;
  33. default: return CallingConvention.Default;
  34. }
  35. }
  36. public void Run()
  37. {
  38. foreach (var mod in _rootModules)
  39. {
  40. foreach (TypeDef type in mod.GetTypes())
  41. {
  42. foreach (MethodDef method in type.Methods)
  43. {
  44. if (method.IsPinvokeImpl)
  45. {
  46. if (!MetaUtil.IsSupportedPInvokeMethodSignature(method.MethodSig))
  47. {
  48. Debug.LogError($"PInvoke method {method.FullName} has unsupported parameter or return type. Please check the method signature.");
  49. }
  50. _pinvokeMethodSignatures.Add(new CallNativeMethodSignatureInfo
  51. {
  52. MethodSig = method.MethodSig,
  53. Callvention = method.HasImplMap? GetCallingConvention(method) : (CallingConvention?)null,
  54. });
  55. }
  56. }
  57. }
  58. }
  59. }
  60. }
  61. }