は、私は次のようなプログラムにモノセシルを使用して、静的コンストラクタを追加しようとしています原因:Mono.Cecilと静的コンストラクタを追加するTypeInitializationException
namespace SimpleTarget
{
class C
{
public void M()
{
Console.WriteLine("Hello, World!");
}
}
}
次のコードは、静的コンストラクタを追加します。
namespace AddStaticConstructor
{
class Program
{
static void Main(string[] args)
{
var assemblyPath = args[0];
var module = ModuleDefinition.ReadModule(assemblyPath);
var corlib = ModuleDefinition.ReadModule(typeof(object).Module.FullyQualifiedName);
var method = corlib.Types.First(t => t.Name.Equals("Console")).Methods.First(m => m.Name.Contains("WriteLine"));
var methodToCall = module.Import(method);
foreach (var type in module.Types)
{
if (!type.Name.Contains("C")) continue;
var staticConstructorAttributes =
Mono.Cecil.MethodAttributes.Private |
Mono.Cecil.MethodAttributes.HideBySig |
Mono.Cecil.MethodAttributes.Static |
Mono.Cecil.MethodAttributes.SpecialName |
Mono.Cecil.MethodAttributes.RTSpecialName;
MethodDefinition staticConstructor = new MethodDefinition(".cctor", staticConstructorAttributes, module.TypeSystem.Void);
type.Methods.Add(staticConstructor);
type.IsBeforeFieldInit = false;
var il = staticConstructor.Body.GetILProcessor();
il.Append(Instruction.Create(OpCodes.Ret));
Instruction ldMethodName = il.Create(OpCodes.Ldstr, type.FullName);
Instruction callOurMethod = il.Create(OpCodes.Call, methodToCall);
Instruction firstInstruction = staticConstructor.Body.Instructions[0];
// Inserts the callOurMethod instruction before the first instruction
il.InsertBefore(firstInstruction, ldMethodName);
il.InsertAfter(ldMethodName, callOurMethod);
}
module.Write(assemblyPath);
}
}
}
dotPeekでデコンパイルされたバイナリを見ると、すべてが正しく設定されているように見えます。 C
タイプを使用しようとすると、内部例外「System.InvalidProgramException:内部制限が発生しました:JITコンパイラが内部制限を検出しました」のTypeInitializationExceptionが発生します。
静的コンストラクタを使用する前に、
ありがとうございます!
var corlib = ModuleDefinition.ReadModule(typeof(object).Module.FullyQualifiedName);
var method = corlib.Types.First(t => t.Name.Equals("Console")).Methods.First(m => m.Name.Contains("WriteLine"));
var methodToCall = module.Import(method);
使用この単純なコードは、使用する過負荷を得る:
[MCVE]を投稿してくださいを。 –