-
Notifications
You must be signed in to change notification settings - Fork 416
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
在不同dll里面注入,fix不同Dll里面的函数,当这些函数具有同样参数类型的匿名函数会出现报错 #384
Comments
ILFixDynamicMethodWrapper这个是Patch中动态生成的,每个程序集都会有,这里的这个实例类型虽然都是ILFixDynamicMethodWrapper,但它们属于不同的程序集,只是名字相同而已,可以改一下这里的代码,这个cache加一级程序集级别的缓存就行。 static Dictionary<string, Dictionary<Type, MethodInfo>> delegateAdptCache = new Dictionary<string, Dictionary<Type, MethodInfo>>();
public static Delegate TryAdapterToDelegate(object obj, Type delegateType, string perfix)
{
MethodInfo method;
if (!delegateAdptCache.TryGetValue(obj.GetType().Assembly.FullName, out var cache))
{
cache = new Dictionary<Type, MethodInfo>();
delegateAdptCache.Add(obj.GetType().Assembly.FullName, cache);
}
if (!cache.TryGetValue(delegateType, out method))
{
MethodInfo delegateMethod = delegateType.GetMethod("Invoke");
var methods = obj.GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
for (int i = 0; i < methods.Length; i++)
{
if (methods[i].Name.StartsWith(perfix) && IsAssignable(delegateMethod, methods[i]))
{
method = methods[i];
cache[delegateType] = method;
}
}
}
if (method == null)
{
return null;
}
else
{
return Delegate.CreateDelegate(delegateType, obj, method);
}
} |
oahceh
pushed a commit
to oahceh/InjectFix
that referenced
this issue
Mar 14, 2023
Closed
Open
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
项目里分了几个dll,对这些dll的函数都进行了配置
在dll A里面对某方法 A进行ifix修复,方法 A里面声明了无参匿名函数,在dll B里面对某方法 B进行ifix修复,方法 B里面也声明了无参匿名函数
先游戏中先调用了方法A后再调用方法B会出现报错,反之也会出现,报错如下:
10:14:13.861 F02286 @t001 Fatal ArgumentException: method arguments are incompatible
IFix.Core.VirtualMachine.Execute (IFix.Core.Instruction* pc, IFix.Core.Value* argumentBase, System.Object[] managedStack, IFix.Core.Value* evaluationStackBase, System.Int32 argsCount, System.Int32 methodIndex, System.Int32 refCount, IFix.Core.Value** topWriteBack) (at <7bfd294e701c4e569265a377b712dfc2>:0)
IFix.Core.VirtualMachine.Execute (System.Int32 methodIndex, IFix.Core.Call& call, System.Int32 argsCount, System.Int32 refCount) (at <7bfd294e701c4e569265a377b712dfc2>:0)
IFix.ILFixDynamicMethodWrapper.__Gen_Wrap_63 (System.Object P0, System.Object P1, System.Object P2) (at <9cadca0bf4564926a0c70bfea602861d>:0)
检查过后发现了在第一次调用的时候会在IFix.Core.Utils的delegateAdptCache字典里面对方法类型进行缓存,在第二次调用的时候会从缓存里面取出同样类型的methodinfo然后执行Delegate.CreateDelegate(delegateType, obj, method1)就会报错,对应出问题的代码
追下去发现
在创建delegate的过程中
实例类型和方法的声明的类runtimetype不同
最后抛出了异常
所以猜测问题是出现在Utils.TryAdapterToDelegate里,在不同的dll里面调用方法的时候
return method1 == (MethodInfo) null ? (Delegate) null : Delegate.CreateDelegate(delegateType, obj, method1);这句里面的obj的实例是不同的,所以它本身的runtimetype也是不同的,实例类型是ILFixDynamicMethodWrapper。但是缓存methodinfo的时候是按照第一个实例来的,就导致了上面出现的报错信息:
Fatal ArgumentException: method arguments are incompatible
不知猜想是否正确,请问有什么合适的解决方法吗
The text was updated successfully, but these errors were encountered: