Pregunta

Estoy generando salida para un ejecutable de .NET desde mi propio idioma ... el código de operación (llamado 'aleatorio') que se está traduciendo de mi idioma se supone que crea un número aleatorio dentro de un rango específico.

El objetivo de mi código es producir el número aleatorio usando System.Reflexion.Emit.ilGenerator Clase ... para comprender cómo se ve el código CIL He creado algún código VB.NET:

Sub Main()
    Dim A As Random

    A = New Random

    Console.WriteLine(A.Next(100))
End Sub

Que informa IlDasm como:

.method public static void  Main() cil managed
{
  .entrypoint
  .custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 ) 
  // Code size       23 (0x17)
  .maxstack  2
  .locals init ([0] class [mscorlib]System.Random A)
  IL_0000:  nop
  IL_0001:  newobj     instance void [mscorlib]System.Random::.ctor()
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  ldc.i4.s   100
  IL_000a:  callvirt   instance int32 [mscorlib]System.Random::Next(int32)
  IL_000f:  call       void [mscorlib]System.Console::WriteLine(int32)
  IL_0014:  nop
  IL_0015:  nop
  IL_0016:  ret
} // end of method Main::Main

Puedo reproducir todo usando el método ILGenerator.Emit; Excepto la línea IL_0001 ("Newobj instancia void [mscorlib] system.random ::. ctor ()") ...

Ojalá no haya abrumado a nadie con demasiada información. Pero creo que es mejor ser detallado al describir un problema que me parece complejo.

Finalmente tengo el código que he producido hasta ahora:

 Sub EmitRandom()
    Dim NewRandom As New Random
    Dim stringtype As Type = GetType(System.Random)

    Dim paramtypes() As Type = {GetType(Integer)}, blankparams() As Type = {}
    'Dim RandomMethod = stringtype.GetMethod("New", paramtypes)

    m_ILGen.Emit(OpCodes.Newobj, New Random().GetType)

    EmitStoreInLocal(tempVariableRnd)
    EmitLoadLocal(tempVariableRnd)

    m_ILGen.Emit(OpCodes.Callvirt, stringtype.GetMethod("Next", paramtypes))
End Sub

Que emite el siguiente código:

.
.
.
IL_0073:  newobj     [mscorlib]System.Random
IL_0078:  stloc.2
IL_0079:  ldloc.2
IL_007a:  callvirt   instance int32 [mscorlib]System.Random::Next(int32)
.
.
.

Cosas que ya he probado:

  • Presentando una forma de apuntar il_gen.emit (opcodes.newobj, ... ctor ()) ... no puedo entender cómo.

  • Avanzar una forma de señalar a New (), ya que eso parece ser lo que .cor () es ... nuevo no se puede usar como cualquier cosa menos un inicializador.

  • Simplemente deshabilitar la función aleatoria hasta que pueda encontrar una mejor manera de emitir.

El problema me parece difícil, pero sé que hay alguien por ahí que entiende la generación del código y MSIL más fácilmente que yo y que está dispuesto a señalar una respuesta.

Gracias por tu tiempo,

Dominante

¿Fue útil?

Solución

Necesita usar el constructorInfo:

 m_ILGen.Emit(OpCodes.Newobj, GetType(Random).GetConstructor(Type.EmptyTypes))

Además, el almacenamiento y la carga del local son innecesarios. Realmente solo quieres el equivalente de nuevo Random (). Siguiente (100), ¿verdad? ... ¿En qué caso el almacenamiento y la carga de un local nunca sucede?

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