From e36bbb9022fbfafc9e46cc18db2e3913ea5cf22c Mon Sep 17 00:00:00 2001 From: walon Date: Mon, 25 Aug 2025 19:23:29 +0800 Subject: [PATCH] [fix] fixed PInvokeAnalyzer bug in computing PInvoke function calling conventions. --- .../CallNativeMethodSignatureInfo.cs | 2 ++ Editor/MethodBridge/Generator.cs | 2 +- Editor/MethodBridge/PInvokeAnalyzer.cs | 20 ++++++++++++++++++- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/Editor/MethodBridge/CallNativeMethodSignatureInfo.cs b/Editor/MethodBridge/CallNativeMethodSignatureInfo.cs index 3459e15..566d9ba 100644 --- a/Editor/MethodBridge/CallNativeMethodSignatureInfo.cs +++ b/Editor/MethodBridge/CallNativeMethodSignatureInfo.cs @@ -5,5 +5,7 @@ namespace HybridCLR.Editor.MethodBridge public class CallNativeMethodSignatureInfo { public MethodSig MethodSig { get; set; } + + public CallingConvention? Callvention { get; set; } } } diff --git a/Editor/MethodBridge/Generator.cs b/Editor/MethodBridge/Generator.cs index 211dcbd..e35ded9 100644 --- a/Editor/MethodBridge/Generator.cs +++ b/Editor/MethodBridge/Generator.cs @@ -638,7 +638,7 @@ namespace HybridCLR.Editor.MethodBridge sharedMethod.Init(); sharedMethod = ToIsomorphicMethod(sharedMethod); - CallingConvention callingConv = (CallingConvention)((int)(method.MethodSig.CallingConvention & dnlib.DotNet.CallingConvention.Mask) + 1); + CallingConvention callingConv = (CallingConvention)((int)((method.Callvention ?? method.MethodSig.CallingConvention) & dnlib.DotNet.CallingConvention.Mask) + 1); string signature = MakeCalliSignature(sharedMethod, callingConv); if (!methodsBySig.TryGetValue(signature, out var arm)) diff --git a/Editor/MethodBridge/PInvokeAnalyzer.cs b/Editor/MethodBridge/PInvokeAnalyzer.cs index 1ddbd3e..51075e4 100644 --- a/Editor/MethodBridge/PInvokeAnalyzer.cs +++ b/Editor/MethodBridge/PInvokeAnalyzer.cs @@ -3,6 +3,7 @@ using HybridCLR.Editor.Meta; using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; using UnityEngine; @@ -26,6 +27,19 @@ namespace HybridCLR.Editor.MethodBridge } } + private CallingConvention GetCallingConvention(MethodDef method) + { + switch (method.ImplMap.CallConv) + { + case PInvokeAttributes.CallConvWinapi: return CallingConvention.Default; + case PInvokeAttributes.CallConvCdecl: return CallingConvention.C; + case PInvokeAttributes.CallConvStdCall: return CallingConvention.StdCall; + case PInvokeAttributes.CallConvThiscall: return CallingConvention.ThisCall; + case PInvokeAttributes.CallConvFastcall: return CallingConvention.FastCall; + default: return CallingConvention.Default; + } + } + public void Run() { foreach (var mod in _rootModules) @@ -40,7 +54,11 @@ namespace HybridCLR.Editor.MethodBridge { Debug.LogError($"PInvoke method {method.FullName} has unsupported parameter or return type. Please check the method signature."); } - _pinvokeMethodSignatures.Add(new CallNativeMethodSignatureInfo { MethodSig = method.MethodSig }); + _pinvokeMethodSignatures.Add(new CallNativeMethodSignatureInfo + { + MethodSig = method.MethodSig, + Callvention = method.HasImplMap? GetCallingConvention(method) : (CallingConvention?)null, + }); } } }