簡體   English   中英

C#MSIL調用方法並傳遞一個對象[]

[英]C# MSIL call method and pass an object[]

我想使用反射發射依賴項將C#中的方法轉換為MSIL代碼。

我要轉換的方法是轉換方法:

public class AClass
{
    public string Transformation(string a, string b, string c)
    {
        return new AnotherClass().Method(new object[] { a, b, c });
    }
}

public class AnotherClass
{
    public string Method(params object[] objs)
    {
        return "AAA";
    }
}

因此,基本上創建一個類的實例,並使用一個新的object []調用方法函數,該對象將處理將所有參數傳遞給它的情況。

當我看着IlSpy時,我有這個:

.method public hidebysig 
instance string Transformation (
    string a,
    string b,
    string c
) cil managed 
{
// Method begins at RVA 0x20d0
// Code size 34 (0x22)
.maxstack 5
.locals init (
    [0] string
)

IL_0000: nop
IL_0001: newobj instance void ConsoleApp1.AnotherClass::.ctor()
IL_0006: ldc.i4.3
IL_0007: newarr [mscorlib]System.Object
IL_000c: dup
IL_000d: ldc.i4.0
IL_000e: ldarg.1
IL_000f: stelem.ref
IL_0010: dup
IL_0011: ldc.i4.1
IL_0012: ldarg.2
IL_0013: stelem.ref
IL_0014: dup
IL_0015: ldc.i4.2
IL_0016: ldarg.3
IL_0017: stelem.ref
IL_0018: call instance string ConsoleApp1.AnotherClass::Method(object[])
IL_001d: stloc.0
IL_001e: br.s IL_0020

IL_0020: ldloc.0
IL_0021: ret
} // end of method AClass::Transformation

並嘗試制作一個表示該函數的函數:

 public static void CallFucntionThroughIl(ILGenerator il, Type[] parameters, MethodInfo method)
    {
        il.Emit(OpCodes.Nop);

        il.Emit(OpCodes.Newobj, typeof(AnotherClass).GetConstructor(Type.EmptyTypes));

        il.Emit(OpCodes.Ldc_I4, parameters.Length);

        il.Emit(OpCodes.Newarr, typeof(object));

        for (int i = 0; i < parameters.Length; i++)
        {
            il.Emit(OpCodes.Dup);
            il.Emit(OpCodes.Ldc_I4, i);
            il.Emit(OpCodes.Ldarg, i + 1);
            il.Emit(OpCodes.Stelem_Ref);
        }

        il.EmitCall(OpCodes.Callvirt,
            typeof(AnotherClass).GetMethod("Method").MakeGenericMethod(method.ReturnType),
            new Type[] { typeof(object[]) });

        il.Emit(OpCodes.Stloc_0);

        var label = il.DefineLabel();

        il.Emit(OpCodes.Br_S, label);

        il.MarkLabel(label);
        il.Emit(OpCodes.Ldloc_0);

        il.Emit(OpCodes.Ret);
    }

但是有時候我不知道自己在做什么,調試時遇到的唯一錯誤是:System.InvalidProgramException:“公共語言運行時檢測到無效程序”。

目標只是復制“ Transformation”函數的作用,獲取所有參數,並將其傳遞到一個object []中,然后在參數中使用該object []調用一個方法,然后返回其他方法返回的內容。

注意:轉換函數並不總是要接收3個字符串,也可以是其他對象。

經過長時間的挖掘:

Nop之后缺少了一個DeclareLocal:

il.Emit(OpCodes.Nop);
il.DeclareLocal(typeof(object[]));

嘗試分配給本地不存在的變量時可能崩潰了。

il.Emit(OpCodes.Stloc_0);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM