2012-03-10 3 views
5

В новейшей версии .NET Framework версии 4.5 класс MethodBuilder имеет метод под названием SetMethodBody, который, я считаю, является именно тем, что я рассматриваю как альтернативу использованию ILGenerator (который раздражающим и ограниченным по-разному). Документацию можно найти here, хотя, поскольку .NET 4.5 еще не завершен, она не полностью документирована. Я могу предоставить все, кроме двух аргументов, но остальное мне потребуется помощь..NET 4.5 MethodBuilder.SetMethodBody

Первое, что я не понимаю, это byte[] localSignature, третий аргумент. MSDN заявляет, что это «массив байтов, который содержит сериализованную локальную структуру переменных. Укажите значение null, если метод не имеет локальных переменных». Проблема в том, что все это говорит, и я не могу узнать формат «сериализованной локальной переменной подписи». Я пробовал смотреть в спецификации ECMA-335, но все, что я нашел, - это указать локальные переменные в незамонтированном CIL. Если бы кто-нибудь мог помочь мне понять это, это было бы очень признательно.

Кроме того, последний аргумент IEnumerable<int> tokenFixups, который представляет собой «набор значений, представляющих смещения в il, каждый из которых указывает начало токена, который может быть изменен. Укажите значение null, если метод не имеет токенов, которые должны быть изменен ". Я подозреваю, что мне не нужно будет использовать их, но я бы хотел знать, что они собой представляют.

Спасибо, Brandon

+5

Вам понадобится класс SignatureHelper. Fixups предназначены только для компиляторов, которые переводят собственный код в IL, например C++/CLI. –

+0

@ Hans Passant: Спасибо за ответ! :) – aboveyou00

ответ

4

Реальный ответ на мой вопрос был отправлен в качестве комментария, вместо ответа, так что в случае, если кто-либо когда-либо имеет этот вопрос ... вот отправил ответ:

Вам понадобится класс SignatureHelper. Fixups предназначены только для компиляторов, которые переводят собственный код в IL, например C++/CLI. - Hans Passant 10 марта в 13:02

Итак ... для того, чтобы получить массив байтов для локальных сигнатур, вы можете выполнить этот код:

var sig = SignatureHelper.GetLocalVarSigHelper(this.module); 
sig.AddArgument(typeof(int)); //Local #0 is of type int 
... 
sig.AddArgument(typeof(string)); //Local #n is of type string 
var sigArray = sig.GetSignature(); 

И для того, чтобы установить метод тело на MethodBuilder, вы звоните

MethodBuilder.SetMethodBody(il, maxStack, sigArray, handlers, fixups); 

... где иль это byte[] с действующими инструкциями IL (см this page), maxStack представляет собой целое число с числом мест для резервирования на стеке для метода, обработчики являются System.Reflection.Emit.ExceptionHandler[] и fixups является int[] массивом, который может быть проигнорирован (с одним исключением, см. ниже)

Единственное, что я не согласен с в комментарии Ганс Passant является то, что fixups не только для составителей которые переводят собственный код в IL. Я обнаружил, что при работе над этим, если вы попытаетесь исправить вызов метода MethodBuilder, он испустит неправильную инструкцию. Рассматривая рефлектор ILGenerator в .NET, я обнаружил, что они испускают исправление каждый раз, когда они испускают вызов метода. Добавление исправления для каждого вызова метода действительно устранило эту проблему. Могут быть и другие места, где вам нужно исправить исправление, чтобы он работал правильно, но я не очень много изучил его.