Pregunta

En la versión más reciente de .NET framework, versión 4.5, la clase MethodBuilder tiene un método llamado SetMethodBody eso 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. aquí, aunque como .NET 4.5 aún no está disponible, no está completamente documentado.Puedo proporcionar todos los argumentos menos dos, pero necesitaré ayuda con el resto.

Lo primero que no entiendo es byte[] localSignature, el tercer argumento.MSDN indica que es "una matriz de bytes que contiene la estructura de la 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". Intenté buscar en la especificación ECMA-335, pero Todo lo que encontré es cómo especificar las variables locales en CIL sin ensamblar.Si alguien pudiera ayudarme a resolver esto, se lo agradecería mucho.

Además, el último argumento es IEnumerable<int> tokenFixups, que es "Una colección de valores que representan compensaciones en il, cada uno de los cuales especifica el comienzo de un token que puede modificarse.Especifique nulo si el método no tiene tokens que deban modificarse".Sospecho que no necesitaré usarlos, pero de todos modos me gustaría saber qué son.

Gracias Brandon

¿Fue útil?

Solución

La verdadera respuesta a mi pregunta se publicó como un comentario, en lugar de una respuesta, así que en caso de que alguien más alguna vez tenga esta pregunta...aquí está la respuesta publicada:

Necesitará la clase SignatureHelper.Las correcciones son solo para compiladores que traducen código nativo a IL, como C++/CLI.– Hans Pasante 10 de marzo a las 13:02

Entonces...Para 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 para configurar el cuerpo del método en MethodBuilder, llamas

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

...donde hay un byte[] con instrucciones IL válidas (consulte esta página), maxStack es un número entero con el número de lugares a reservar en la pila para el método, handlers es un System.Reflection.Emit.ExceptionHandler[], y las reparaciones son una int[] matriz que se puede ignorar (con una excepción, ver más abajo).

Una cosa con la que no estoy de acuerdo en el comentario de Hans Passant es que las correcciones no son solo para compiladores que traducen código nativo a IL.Descubrí mientras trabajaba en esto que si intentas emitir una llamada a un MethodBuilder método, emite la instrucción incorrecta.Al observar ILGenerator en el reflector .NET, descubrí que emiten una corrección cada vez que emiten una llamada a un método.Agregar una solución para cada llamada a método solucionó este problema.Puede que haya otros lugares donde necesites realizar una reparación para que funcione correctamente, pero no lo he investigado mucho.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top