2012-03-10 30 views
5

En la versión más reciente de .NET framework, versión 4.5, la clase MethodBuilder tiene un método llamado SetMethodBody que creo que es exactamente lo que estoy viendo como una alternativa al uso de ILGenerator (que es molesto y limitado de maneras extrañas). La documentación se puede encontrar en here, aunque debido a que .NET 4.5 aún no ha salido, no está completamente documentada. Puedo proporcionar todos menos dos de los argumentos, pero el resto necesitaré ayuda..NET 4.5 MethodBuilder.SetMethodBody

Lo primero que no entiendo es byte[] localSignature, el tercer argumento. MSDN afirma que es "Una matriz de bytes que contiene la estructura de variable local serializada. Especifique nulo si el método no tiene variables locales". El problema es que eso es todo lo que dice, y no puedo encontrar el formato de una "firma de variable local serializada". He intentado buscar en la especificación ECMA-335, pero todo lo que he encontrado es cómo especificar las variables locales en CIL sin ensamblar. Si alguien pudiera ayudarme a resolver esto, sería muy apreciado.

Además, el último argumento es IEnumerable<int> tokenFixups, que es "Una colección de valores que representan desplazamientos en il, cada uno de los cuales especifica el comienzo de un token que se puede modificar. Especifique nulo si el método no tiene tokens que deben ser modificado.". Sospecho que no necesitaré usar estos, pero me gustaría saber cuáles son de todos modos.

Gracias, Brandon

+5

Necesitará la clase SignatureHelper. Las reparaciones solo son para compiladores que traducen código nativo a IL, como C++/CLI. –

+0

@ Hans Passant: ¡gracias por la respuesta! :) – aboveyou00

Respuesta

4

La verdadera respuesta a mi pregunta fue publicada como un comentario, en lugar de una respuesta, por lo que en caso de que alguien más ha esta pregunta ... Aquí está la respuesta publicado:

Necesitará la clase SignatureHelper. Las reparaciones solo son para compiladores que traducen código nativo a IL, como C++/CLI. - Hans Passant Mar 10 en el 13:02

Así que ... con el fin de obtener la matriz de bytes para las firmas locales, puede ejecutar este código:

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(); 

Y con el fin de establecer el método cuerpo sobre el MethodBuilder, te llama

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

... donde IL es una byte[] con instrucciones IL válidos (ver this page), maxStack es un entero con el número de puntos a reservar en la pila para el método, los manipuladores es un System.Reflection.Emit.ExceptionHandler[] y fixups es una matriz int[] que puede ser ignorada (con una excepción, véase más adelante).

Una cosa que no estoy de acuerdo con en el comentario de Hans Passant es que fixups no son sólo para los compiladores que traducen código nativo a IL. Al trabajar en esto, descubrí que si intentas emitir una llamada a un método MethodBuilder, emite las instrucciones incorrectas. Al observar ILGenerator en el reflector .NET, descubrí que emiten una corrección cada vez que emiten una llamada a un método. La adición de una corrección para cada llamada de método de hecho solucionó este problema. Puede haber otros lugares donde necesite emitir una corrección para que funcione correctamente, pero no he investigado mucho.

Cuestiones relacionadas