From b301b44cd35f592c7ed8d5aaaffd23d425eb07ed Mon Sep 17 00:00:00 2001 From: walon Date: Wed, 30 Apr 2025 16:20:03 +0800 Subject: [PATCH] [refactor] move ReversePInvokeWrap/Analyzer.cs to MethodBridge/MonoPInvokeCallbackAnalyzer.cs [change] validate unsupported parameter type(.e.g string) in MonoPInvokeCallback signature when generate MethodBridge file --- .../Commands/MethodBridgeGeneratorCommand.cs | 5 ++-- Editor/Meta/MetaUtil.cs | 24 +++++++++++++++++ Editor/MethodBridge/Generator.cs | 7 +++-- .../MonoPInvokeCallbackAnalyzer.cs} | 20 ++++++++------ .../MonoPInvokeCallbackAnalyzer.cs.meta} | 0 Editor/MethodBridge/PInvokeAnalyzer.cs | 26 +------------------ 6 files changed, 42 insertions(+), 40 deletions(-) rename Editor/{ReversePInvokeWrap/Analyzer.cs => MethodBridge/MonoPInvokeCallbackAnalyzer.cs} (68%) rename Editor/{ReversePInvokeWrap/Analyzer.cs.meta => MethodBridge/MonoPInvokeCallbackAnalyzer.cs.meta} (100%) diff --git a/Editor/Commands/MethodBridgeGeneratorCommand.cs b/Editor/Commands/MethodBridgeGeneratorCommand.cs index 38f36b0..0ebdce0 100644 --- a/Editor/Commands/MethodBridgeGeneratorCommand.cs +++ b/Editor/Commands/MethodBridgeGeneratorCommand.cs @@ -2,7 +2,6 @@ using HybridCLR.Editor.ABI; using HybridCLR.Editor.Meta; using HybridCLR.Editor.MethodBridge; -using HybridCLR.Editor.ReversePInvokeWrap; using System; using System.Collections.Generic; using System.IO; @@ -31,7 +30,7 @@ namespace HybridCLR.Editor.Commands Directory.Delete(il2cppBuildCachePath, true); } - private static void GenerateMethodBridgeCppFile(IReadOnlyCollection genericMethods, List reversePInvokeMethods, IReadOnlyCollection calliMethodSignatures, string tempFile, string outputFile) + private static void GenerateMethodBridgeCppFile(IReadOnlyCollection genericMethods, List reversePInvokeMethods, IReadOnlyCollection calliMethodSignatures, string tempFile, string outputFile) { string templateCode = File.ReadAllText(tempFile, Encoding.UTF8); var g = new Generator(new Generator.Options() @@ -78,7 +77,7 @@ namespace HybridCLR.Editor.Commands List hotUpdateDlls = SettingsUtil.HotUpdateAssemblyNamesExcludePreserved; var cache = new AssemblyCache(MetaUtil.CreateHotUpdateAndAOTAssemblyResolver(target, hotUpdateDlls)); - var reversePInvokeAnalyzer = new ReversePInvokeWrap.Analyzer(cache, hotUpdateDlls); + var reversePInvokeAnalyzer = new MonoPInvokeCallbackAnalyzer(cache, hotUpdateDlls); reversePInvokeAnalyzer.Run(); var calliAnalyzer = new CalliAnalyzer(cache, hotUpdateDlls); diff --git a/Editor/Meta/MetaUtil.cs b/Editor/Meta/MetaUtil.cs index 5f1b96c..2302540 100644 --- a/Editor/Meta/MetaUtil.cs +++ b/Editor/Meta/MetaUtil.cs @@ -189,5 +189,29 @@ namespace HybridCLR.Editor.Meta } return methodGenericParams; } + + public static bool IsSupportedPInvokeTypeSig(TypeSig typeSig) + { + typeSig = typeSig.RemovePinnedAndModifiers(); + if (typeSig.IsByRef) + { + return true; + } + switch (typeSig.ElementType) + { + case ElementType.SZArray: + case ElementType.Array: + //case ElementType.Class: + case ElementType.String: + //case ElementType.Object: + return false; + default: return true; + } + } + + public static bool IsSupportedPInvokeMethodSignature(MethodSig methodSig) + { + return IsSupportedPInvokeTypeSig(methodSig.RetType) && methodSig.Params.All(p => IsSupportedPInvokeTypeSig(p)); + } } } diff --git a/Editor/MethodBridge/Generator.cs b/Editor/MethodBridge/Generator.cs index 71f8344..185f05e 100644 --- a/Editor/MethodBridge/Generator.cs +++ b/Editor/MethodBridge/Generator.cs @@ -1,7 +1,6 @@ using dnlib.DotNet; using HybridCLR.Editor.ABI; using HybridCLR.Editor.Meta; -using HybridCLR.Editor.ReversePInvokeWrap; using HybridCLR.Editor.Template; using System; using System.Collections.Generic; @@ -30,7 +29,7 @@ namespace HybridCLR.Editor.MethodBridge public IReadOnlyCollection GenericMethods { get; set; } - public List ReversePInvokeMethods { get; set; } + public List ReversePInvokeMethods { get; set; } public IReadOnlyCollection CalliMethodSignatures { get; set; } @@ -59,7 +58,7 @@ namespace HybridCLR.Editor.MethodBridge private readonly List _genericMethods; - private readonly List _originalReversePInvokeMethods; + private readonly List _originalReversePInvokeMethods; private readonly List _originalCalliMethodSignatures; @@ -588,7 +587,7 @@ namespace HybridCLR.Editor.MethodBridge return (CallingConvention)conv; } - private List BuildABIMethods(List rawMethods) + private List BuildABIMethods(List rawMethods) { var methodsBySig = new Dictionary(); foreach (var method in rawMethods) diff --git a/Editor/ReversePInvokeWrap/Analyzer.cs b/Editor/MethodBridge/MonoPInvokeCallbackAnalyzer.cs similarity index 68% rename from Editor/ReversePInvokeWrap/Analyzer.cs rename to Editor/MethodBridge/MonoPInvokeCallbackAnalyzer.cs index 0004d18..cfc56e6 100644 --- a/Editor/ReversePInvokeWrap/Analyzer.cs +++ b/Editor/MethodBridge/MonoPInvokeCallbackAnalyzer.cs @@ -9,25 +9,25 @@ using System.Threading.Tasks; using CallingConvention = System.Runtime.InteropServices.CallingConvention; using UnityEngine; -namespace HybridCLR.Editor.ReversePInvokeWrap +namespace HybridCLR.Editor.MethodBridge { - public class RawReversePInvokeMethodInfo + public class RawMonoPInvokeCallbackMethodInfo { public MethodDef Method { get; set; } public CustomAttribute GenerationAttribute { get; set; } } - public class Analyzer + public class MonoPInvokeCallbackAnalyzer { private readonly List _rootModules = new List(); - private readonly List _reversePInvokeMethods = new List(); + private readonly List _reversePInvokeMethods = new List(); - public List ReversePInvokeMethods => _reversePInvokeMethods; + public List ReversePInvokeMethods => _reversePInvokeMethods; - public Analyzer(AssemblyCache cache, List assemblyNames) + public MonoPInvokeCallbackAnalyzer(AssemblyCache cache, List assemblyNames) { foreach (var assemblyName in assemblyNames) { @@ -39,7 +39,7 @@ namespace HybridCLR.Editor.ReversePInvokeWrap { foreach (var mod in _rootModules) { - Debug.Log($"ass:{mod.FullName} methodcount:{mod.Metadata.TablesStream.MethodTable.Rows}"); + Debug.Log($"ass:{mod.FullName} method count:{mod.Metadata.TablesStream.MethodTable.Rows}"); for (uint rid = 1, n = mod.Metadata.TablesStream.MethodTable.Rows; rid <= n; rid++) { var method = mod.ResolveMethod(rid); @@ -53,11 +53,15 @@ namespace HybridCLR.Editor.ReversePInvokeWrap { continue; } + if (!MetaUtil.IsSupportedPInvokeMethodSignature(method.MethodSig)) + { + throw new Exception($"MonoPInvokeCallback method {method.FullName} has unsupported parameter or return type. Please check the method signature."); + } //foreach (var ca in method.CustomAttributes) //{ // Debug.Log($"{ca.AttributeType.FullName} {ca.TypeFullName}"); //} - _reversePInvokeMethods.Add(new RawReversePInvokeMethodInfo() + _reversePInvokeMethods.Add(new RawMonoPInvokeCallbackMethodInfo() { Method = method, GenerationAttribute = method.CustomAttributes.FirstOrDefault(ca => ca.AttributeType.FullName == "HybridCLR.ReversePInvokeWrapperGenerationAttribute"), diff --git a/Editor/ReversePInvokeWrap/Analyzer.cs.meta b/Editor/MethodBridge/MonoPInvokeCallbackAnalyzer.cs.meta similarity index 100% rename from Editor/ReversePInvokeWrap/Analyzer.cs.meta rename to Editor/MethodBridge/MonoPInvokeCallbackAnalyzer.cs.meta diff --git a/Editor/MethodBridge/PInvokeAnalyzer.cs b/Editor/MethodBridge/PInvokeAnalyzer.cs index c12d5a0..1729b82 100644 --- a/Editor/MethodBridge/PInvokeAnalyzer.cs +++ b/Editor/MethodBridge/PInvokeAnalyzer.cs @@ -26,30 +26,6 @@ namespace HybridCLR.Editor.MethodBridge } } - private static bool IsSupportedPInvokeTypeSig(TypeSig typeSig) - { - typeSig = typeSig.RemovePinnedAndModifiers(); - if (typeSig.IsByRef) - { - return true; - } - switch (typeSig.ElementType) - { - case ElementType.SZArray: - case ElementType.Array: - //case ElementType.Class: - case ElementType.String: - //case ElementType.Object: - return false; - default: return true; - } - } - - private static bool IsSupportedPInvokeMethodSignature(MethodSig methodSig) - { - return IsSupportedPInvokeTypeSig(methodSig.RetType) && methodSig.Params.All(p => IsSupportedPInvokeTypeSig(p)); - } - public void Run() { foreach (var mod in _rootModules) @@ -60,7 +36,7 @@ namespace HybridCLR.Editor.MethodBridge { if (method.IsPinvokeImpl) { - if (!IsSupportedPInvokeMethodSignature(method.MethodSig)) + if (!MetaUtil.IsSupportedPInvokeMethodSignature(method.MethodSig)) { throw new Exception($"PInvoke method {method.FullName} has unsupported parameter or return type. Please check the method signature."); }