[refactor] move ReversePInvokeWrap/Analyzer.cs to MethodBridge/MonoPInvokeCallbackAnalyzer.cs

[change] validate unsupported parameter type(.e.g string) in MonoPInvokeCallback signature when generate MethodBridge file
main
walon 2025-04-30 16:20:03 +08:00
parent ddc3332958
commit b301b44cd3
6 changed files with 42 additions and 40 deletions

View File

@ -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<GenericMethod> genericMethods, List<RawReversePInvokeMethodInfo> reversePInvokeMethods, IReadOnlyCollection<CallNativeMethodSignatureInfo> calliMethodSignatures, string tempFile, string outputFile)
private static void GenerateMethodBridgeCppFile(IReadOnlyCollection<GenericMethod> genericMethods, List<RawMonoPInvokeCallbackMethodInfo> reversePInvokeMethods, IReadOnlyCollection<CallNativeMethodSignatureInfo> 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<string> 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);

View File

@ -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));
}
}
}

View File

@ -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<GenericMethod> GenericMethods { get; set; }
public List<RawReversePInvokeMethodInfo> ReversePInvokeMethods { get; set; }
public List<RawMonoPInvokeCallbackMethodInfo> ReversePInvokeMethods { get; set; }
public IReadOnlyCollection<CallNativeMethodSignatureInfo> CalliMethodSignatures { get; set; }
@ -59,7 +58,7 @@ namespace HybridCLR.Editor.MethodBridge
private readonly List<GenericMethod> _genericMethods;
private readonly List<RawReversePInvokeMethodInfo> _originalReversePInvokeMethods;
private readonly List<RawMonoPInvokeCallbackMethodInfo> _originalReversePInvokeMethods;
private readonly List<CallNativeMethodSignatureInfo> _originalCalliMethodSignatures;
@ -588,7 +587,7 @@ namespace HybridCLR.Editor.MethodBridge
return (CallingConvention)conv;
}
private List<ABIReversePInvokeMethodInfo> BuildABIMethods(List<RawReversePInvokeMethodInfo> rawMethods)
private List<ABIReversePInvokeMethodInfo> BuildABIMethods(List<RawMonoPInvokeCallbackMethodInfo> rawMethods)
{
var methodsBySig = new Dictionary<string, ABIReversePInvokeMethodInfo>();
foreach (var method in rawMethods)

View File

@ -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<ModuleDefMD> _rootModules = new List<ModuleDefMD>();
private readonly List<RawReversePInvokeMethodInfo> _reversePInvokeMethods = new List<RawReversePInvokeMethodInfo>();
private readonly List<RawMonoPInvokeCallbackMethodInfo> _reversePInvokeMethods = new List<RawMonoPInvokeCallbackMethodInfo>();
public List<RawReversePInvokeMethodInfo> ReversePInvokeMethods => _reversePInvokeMethods;
public List<RawMonoPInvokeCallbackMethodInfo> ReversePInvokeMethods => _reversePInvokeMethods;
public Analyzer(AssemblyCache cache, List<string> assemblyNames)
public MonoPInvokeCallbackAnalyzer(AssemblyCache cache, List<string> assemblyNames)
{
foreach (var assemblyName in assemblyNames)
{
@ -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"),

View File

@ -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.");
}