Добавьте поле статического экземпляра в класс и установите значение Self в конструкторе

#c# #mono.cecil

Вопрос:

Используя Моно.Сесил, я пытаюсь исправить класс, чтобы добавить статическое поле «Экземпляр» и установить его внутри конструктора. По сути, это эквивалентно добавлению следующего:

 public static Class1 Instance;
public Class1() {
    // does normal constructor stuff
    Class1.Instance = this;
}
 

Однако я не знаю, где существует ссылка, и, просмотрев коды операций, я не смог найти, как я мог бы поместить ссылку в стек для хранения поля (коды операций.Stfld) в мое определение поля.

Однако вот что у меня есть на данный момент.

 public static void Patch(AssemblyDefinition assembly) {
    TypeDefinition wfcDefinition = assembly.MainModule.Types.First(t => t.Name == "WinFormConnection");
    MethodDefinition wfcConstructor = wfcDefinition.GetConstructors().First(t => t.IsConstructor);

    FieldDefinition instField = new FieldDefinition("Instance", FieldAttributes.Public | FieldAttributes.Static, wfcConstructor.DeclaringType);
    wfcDefinition.Fields.Add(instField);

    ILProcessor proc = wfcConstructor.Body.GetILProcessor();

    // Where does the instance exist within the stack?
    // Instruction pushInstance = proc.Create(OpCodes.?);
    Instruction allocInstance = proc.Create(OpCodes.Stfld, instField);

    // proc.Body.Instructions.Add(pushInstance);
    proc.Body.Instructions.Add(allocInstance);
}
 

Ответ №1:

это всегда первый аргумент метода, т. е. вам нужно сделать что-то вроде:

 ...
  Instruction pushInstance = proc.Create(OpCodes.Ldarg_0);
  proc.Body.Instructions.Add(pushInstance);

  Instruction store = proc.Create(OpCodes.Stsfld, instField);
  proc.Body.Instructions.Add(store);
 

также обратите внимание, что вам нужно использовать Stsfld (статическое поле хранилища) вместо Stfld (поле экземпляра хранилища).

Комментарии:

1. Спасибо вам за это! Я решил эту проблему ранее, создав сборку с точным кодом, который я пытался реализовать, и это именно то, что я нашел.

2. неплохо. Кстати, вы всегда можете использовать cecilifier.me чтобы помочь вам понять, как использовать Моно. Сесил для достижения какой-то цели (отказ от ответственности, я являюсь автором cecilifier 🙂 )