我在程序集中有字节码。我想将此代码复制到另一个程序集。这并不容易,但乍一看我得到了一个很好的副本。我可以复制命名空间、类、自定义属性、字段等。但是我对方法体有疑问。
我知道我可以通过以下方式获取代码:
byte[] ilCode = method.GetMethodBody().GetILAsByteArray();
此外,我知道如何设置新方法 Body:
MethodBuilder methodBuilder = typeBuilder.DefineMethod(method.Name, method.Attributes, method.CallingConvention, method.ReturnType, param.ToArray());
methodBuilder.SetMethodBody(ilCode, method.GetMethodBody().MaxStackSize, sig.GetSignature(), exce, null);
变量定义如下:
- method : MethodInfo //原始方法
- param : List //参数类型列表
- exec : List // 所有异常子句的列表
- sig : SignatureHelper //不太确定,但与当地人有关
现在我有以下结果:
首先是原始方法:
.method private hidebysig instance void onTargetFloorReached() cil managed
{
// Code size 12 (0xc)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldstr "TargetFloorReached"
IL_0006: call instance void ['Assembly-CSharp']BaseWeb::CallFunctionWithParameter(string)
IL_000b: ret
} // end of method Lift::onTargetFloorReached
现在,我在另一边得到了什么:
.method private hidebysig instance void onTargetFloorReached() cil managed
{
// Code size 12 (0xc)
.maxstack 8
IL_0000: ldarg.0
INVALID TOKEN: 0x70000001
IL_0006: call [ERROR: INVALID TOKEN 0x0A00000D]
IL_000b: ret
} // end of method Lift::onTargetFloorReached
我已经尝试加载原始 dll 的每个依赖项,但这不会改变任何东西。
SetMethodBody 方法定义为:
public void SetMethodBody (byte[] il, int maxStack, byte[] localSignature, System.Collections.Generic.IEnumerable<System.Reflection.Emit.ExceptionHandler> exceptionHandlers, System.Collections.Generic.IEnumerable<int> tokenFixups);
没有关于“tokenFixups”的信息。
这些修正是什么?我怎样才能得到它们?或者错误可能在其他地方?
编辑:似乎只有函数调用是无效的。如果我可以从它的字节表示中识别函数,我可以解决这个问题。