ILCode编译时出现错误-C#
/请跳到更新, 将NETFramework3.5(Mono)与C#7.0结合使用 我正在尝试创建一个动态方法,该方法获取它的参数,将它们放入对象数组,并在simple方法上调用它 然后在运行时,我通过不安全上下文替换方法。(这样做是为了更好的API) 我按照自己的想象创建了代码,并在LINQPad 5中发布了该代码ILCode编译时出现错误-C#,c#,C#,/请跳到更新, 将NETFramework3.5(Mono)与C#7.0结合使用 我正在尝试创建一个动态方法,该方法获取它的参数,将它们放入对象数组,并在simple方法上调用它 然后在运行时,我通过不安全上下文替换方法。(这样做是为了更好的API) 我按照自己的想象创建了代码,并在LINQPad 5中发布了该代码 void TestCall(string a, int b) { NetworkInvoke(a, b); } void NetworkInvoke(params obje
void TestCall(string a, int b) {
NetworkInvoke(a, b);
}
void NetworkInvoke(params object[] parameters) {
}
在LINQPad中,我有IL代码:
g__TestCall0_0:
IL_0000: nop
IL_0001: ldc.i4.2
IL_0002: newarr System.Object
IL_0007: dup
IL_0008: ldc.i4.0
IL_0009: ldarg.0
IL_000A: stelem.ref
IL_000B: dup
IL_000C: ldc.i4.1
IL_000D: ldarg.1
IL_000E: box System.Int32
IL_0013: stelem.ref
IL_0014: call g__NetworkInvoke0_1
IL_0019: nop
IL_001A: ret
现在让我们在ILGenerator中重新创建它。(我已经有了支持所有参数的代码,但它也不起作用。然后我创建了这个简单的静态代码,但它也不起作用)
当我调用它时,我收到invalidProgrammeException
InvalidProgrameException:中的IL代码无效(包装器动态方法)
脚本:TestCall(string,int):IL_000b:stelem.ref
我试图删除引用-(Stelem_Ref)然后我得到了
InvalidProgrameException:中的IL代码无效(包装器动态方法)
脚本:TestCall(string,int):IL_000d:ldarg.2
知道我做错了什么吗?谢谢你给我小费
更新,嗯,看起来我在这里发布了错误的代码。
(我昨天几乎一整天都在努力解决这个问题)
当我将ILCode重写为正确的时(对不起,我的错误)
我有
InvalidProgrameException:中的IL代码无效(包装器动态方法)
脚本:TestCall(string,int):IL_0014:call0x00000005 这是正确的错误 更新2 我创建了Debug,当比较这两种方法时,它们看起来是一样的
private void DebugM(MethodInfo method) {
var builder = new StringBuilder();
builder.Append("Name: ").Append(method.Name);
builder.Append("\nParameters(").Append(method.GetParameters().Length).Append("): ");
foreach (var parameter in method.GetParameters()) {
builder.Append("(").Append(parameter.ParameterType.FullName).Append(")");
}
builder.Append("\nReturnType: ").Append(method.ReturnType.FullName);
builder.Append("\nMemberType: ").Append(method.MemberType);
builder.Append("\nCC: ").Append(method.CallingConvention);
builder.Append("\nModule: ").Append(method.Module.Name);
Debug.Log(builder.ToString());
}
名称:TestCall参数(2):(System.String)(System.Int32)
ReturnType:System.Void成员类型:方法CC:Standard,HasThis
模块:Assembly-CSharp.dll
我创建了与正在重新创建的完全相同的方法:
检测是否是由于参数计数引起的
方法正在重新创建的内容:
public void TestCall(string testString, int testInt) {
Debug.Log("Called TestCAll with params: " + testInt + ", " + testInt);
}
要调用的方法:
internal void TestMethod(string a, int b) {
Debug.Log("Called TestMethod!!");
}
我试图用委托调用它:
public delegate void TestDelegate(String a, int b);
//In end of CreateMethodFrom
var delTest = (TestDelegate) dynMethod.CreateDelegate(typeof(TestDelegate));
delTest("TESTA", 31321321);
结果是一样的:
InvalidProgrameException:中的IL代码无效(包装器动态方法)
脚本:TestCall(string,int):IL_0014:call0x00000005 堆栈跟踪
System.Delegate.CreateDelegate (System.Type type, System.Object firstArgument, System.Reflection.MethodInfo method, Boolean throwOnBindFailure) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System/Delegate.cs:268)
System.Delegate.CreateDelegate (System.Type type, System.Reflection.MethodInfo method, Boolean throwOnBindFailure) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System/Delegate.cs:291)
System.Delegate.CreateDelegate (System.Type type, System.Reflection.MethodInfo method) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System/Delegate.cs:295)
System.Reflection.Emit.DynamicMethod.CreateDelegate (System.Type delegateType) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection.Emit/DynamicMethod.cs:179)
SioFramework.Script.CreateMethodFrom (System.Reflection.MethodInfo method) (at Assets/SioFramework/Script.cs:167)
167:
您显示的IL和您发出的IL不一样(请看
ldarg
说明)哦,是的,对不起,我尝试了一些测试,但忘记返回原始值。更新到正确的代码是否已使用newdynamicmethod
创建实例方法?我只创建了静态方法。在这种情况下,如果将NetworkInvoke
设置为static,我就成功地使它工作了。看起来调用的方法确实缺少实例。如果dynamicmethod是实例方法,则ldarg\u 0
返回this
指针(从而移动其余参数)。同样,如果要调用实例方法,则必须在堆栈上放置对该方法的引用,然后再调用其他参数。
internal void TestMethod(string a, int b) {
Debug.Log("Called TestMethod!!");
}
public delegate void TestDelegate(String a, int b);
//In end of CreateMethodFrom
var delTest = (TestDelegate) dynMethod.CreateDelegate(typeof(TestDelegate));
delTest("TESTA", 31321321);
System.Delegate.CreateDelegate (System.Type type, System.Object firstArgument, System.Reflection.MethodInfo method, Boolean throwOnBindFailure) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System/Delegate.cs:268)
System.Delegate.CreateDelegate (System.Type type, System.Reflection.MethodInfo method, Boolean throwOnBindFailure) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System/Delegate.cs:291)
System.Delegate.CreateDelegate (System.Type type, System.Reflection.MethodInfo method) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System/Delegate.cs:295)
System.Reflection.Emit.DynamicMethod.CreateDelegate (System.Type delegateType) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection.Emit/DynamicMethod.cs:179)
SioFramework.Script.CreateMethodFrom (System.Reflection.MethodInfo method) (at Assets/SioFramework/Script.cs:167)
var delTest = (TestDelegate) dynMethod.CreateDelegate(typeof(TestDelegate));