[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.ABI;
using HybridCLR.Editor.Meta; using HybridCLR.Editor.Meta;
using HybridCLR.Editor.MethodBridge; using HybridCLR.Editor.MethodBridge;
using HybridCLR.Editor.ReversePInvokeWrap;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
@ -31,7 +30,7 @@ namespace HybridCLR.Editor.Commands
Directory.Delete(il2cppBuildCachePath, true); 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); string templateCode = File.ReadAllText(tempFile, Encoding.UTF8);
var g = new Generator(new Generator.Options() var g = new Generator(new Generator.Options()
@ -78,7 +77,7 @@ namespace HybridCLR.Editor.Commands
List<string> hotUpdateDlls = SettingsUtil.HotUpdateAssemblyNamesExcludePreserved; List<string> hotUpdateDlls = SettingsUtil.HotUpdateAssemblyNamesExcludePreserved;
var cache = new AssemblyCache(MetaUtil.CreateHotUpdateAndAOTAssemblyResolver(target, hotUpdateDlls)); var cache = new AssemblyCache(MetaUtil.CreateHotUpdateAndAOTAssemblyResolver(target, hotUpdateDlls));
var reversePInvokeAnalyzer = new ReversePInvokeWrap.Analyzer(cache, hotUpdateDlls); var reversePInvokeAnalyzer = new MonoPInvokeCallbackAnalyzer(cache, hotUpdateDlls);
reversePInvokeAnalyzer.Run(); reversePInvokeAnalyzer.Run();
var calliAnalyzer = new CalliAnalyzer(cache, hotUpdateDlls); var calliAnalyzer = new CalliAnalyzer(cache, hotUpdateDlls);

View File

@ -189,5 +189,29 @@ namespace HybridCLR.Editor.Meta
} }
return methodGenericParams; 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 dnlib.DotNet;
using HybridCLR.Editor.ABI; using HybridCLR.Editor.ABI;
using HybridCLR.Editor.Meta; using HybridCLR.Editor.Meta;
using HybridCLR.Editor.ReversePInvokeWrap;
using HybridCLR.Editor.Template; using HybridCLR.Editor.Template;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -30,7 +29,7 @@ namespace HybridCLR.Editor.MethodBridge
public IReadOnlyCollection<GenericMethod> GenericMethods { get; set; } public IReadOnlyCollection<GenericMethod> GenericMethods { get; set; }
public List<RawReversePInvokeMethodInfo> ReversePInvokeMethods { get; set; } public List<RawMonoPInvokeCallbackMethodInfo> ReversePInvokeMethods { get; set; }
public IReadOnlyCollection<CallNativeMethodSignatureInfo> CalliMethodSignatures { get; set; } public IReadOnlyCollection<CallNativeMethodSignatureInfo> CalliMethodSignatures { get; set; }
@ -59,7 +58,7 @@ namespace HybridCLR.Editor.MethodBridge
private readonly List<GenericMethod> _genericMethods; private readonly List<GenericMethod> _genericMethods;
private readonly List<RawReversePInvokeMethodInfo> _originalReversePInvokeMethods; private readonly List<RawMonoPInvokeCallbackMethodInfo> _originalReversePInvokeMethods;
private readonly List<CallNativeMethodSignatureInfo> _originalCalliMethodSignatures; private readonly List<CallNativeMethodSignatureInfo> _originalCalliMethodSignatures;
@ -588,7 +587,7 @@ namespace HybridCLR.Editor.MethodBridge
return (CallingConvention)conv; return (CallingConvention)conv;
} }
private List<ABIReversePInvokeMethodInfo> BuildABIMethods(List<RawReversePInvokeMethodInfo> rawMethods) private List<ABIReversePInvokeMethodInfo> BuildABIMethods(List<RawMonoPInvokeCallbackMethodInfo> rawMethods)
{ {
var methodsBySig = new Dictionary<string, ABIReversePInvokeMethodInfo>(); var methodsBySig = new Dictionary<string, ABIReversePInvokeMethodInfo>();
foreach (var method in rawMethods) foreach (var method in rawMethods)

View File

@ -9,25 +9,25 @@ using System.Threading.Tasks;
using CallingConvention = System.Runtime.InteropServices.CallingConvention; using CallingConvention = System.Runtime.InteropServices.CallingConvention;
using UnityEngine; using UnityEngine;
namespace HybridCLR.Editor.ReversePInvokeWrap namespace HybridCLR.Editor.MethodBridge
{ {
public class RawReversePInvokeMethodInfo public class RawMonoPInvokeCallbackMethodInfo
{ {
public MethodDef Method { get; set; } public MethodDef Method { get; set; }
public CustomAttribute GenerationAttribute { get; set; } public CustomAttribute GenerationAttribute { get; set; }
} }
public class Analyzer public class MonoPInvokeCallbackAnalyzer
{ {
private readonly List<ModuleDefMD> _rootModules = new List<ModuleDefMD>(); 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) foreach (var assemblyName in assemblyNames)
{ {
@ -53,11 +53,15 @@ namespace HybridCLR.Editor.ReversePInvokeWrap
{ {
continue; 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) //foreach (var ca in method.CustomAttributes)
//{ //{
// Debug.Log($"{ca.AttributeType.FullName} {ca.TypeFullName}"); // Debug.Log($"{ca.AttributeType.FullName} {ca.TypeFullName}");
//} //}
_reversePInvokeMethods.Add(new RawReversePInvokeMethodInfo() _reversePInvokeMethods.Add(new RawMonoPInvokeCallbackMethodInfo()
{ {
Method = method, Method = method,
GenerationAttribute = method.CustomAttributes.FirstOrDefault(ca => ca.AttributeType.FullName == "HybridCLR.ReversePInvokeWrapperGenerationAttribute"), 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() public void Run()
{ {
foreach (var mod in _rootModules) foreach (var mod in _rootModules)
@ -60,7 +36,7 @@ namespace HybridCLR.Editor.MethodBridge
{ {
if (method.IsPinvokeImpl) 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."); throw new Exception($"PInvoke method {method.FullName} has unsupported parameter or return type. Please check the method signature.");
} }