我在一个程序集中有ByteCode。我想将此代码复制到另一个程序集。这并不容易,但我第一眼就看到了很好的副本。我可以复制命名空间,类,自定义属性,字段等。但是我对方法Bodys有一个问题。
我知道我可以通过以下方式获取代码:
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 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”的信息。
这些修正是什么?我怎么能得到它们?或者可能是其他地方的错误?
编辑:似乎只有函数调用无效。如果我能从其字节表示中识别该函数,我可以解决这个问题。
您应该使用https://github.com/dotnet/ILMerge或https://github.com/gluck/il-repack等现有工具,它们允许您将dll和exe组合到一个文件中。
至于两次加载相同的类,如果程序集已经在app域中加载,即使程序集版本以某种方式不同(我相信),也不会加载两次。所以我不明白这是怎么回事。