ILCode编译时出现错误-C#

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

/请跳到更新,

将NETFramework3.5(Mono)与C#7.0结合使用

我正在尝试创建一个动态方法,该方法获取它的参数,将它们放入对象数组,并在simple方法上调用它

然后在运行时,我通过不安全上下文替换方法。(这样做是为了更好的API)

我按照自己的想象创建了代码,并在LINQPad 5中发布了该代码

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:call
0x00000005

这是正确的错误

更新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:call
0x00000005

堆栈跟踪

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