Domanda

Sto generazione di output per un .Net eseguibile dalla mia lingua ... il codice operativo (chiamato 'a caso') che viene tradotto da mia lingua si suppone di creare un numero casuale all'interno di una gamma specifica.

L'obiettivo per il mio codice è quello di produrre il numero casuale utilizzando la classe System.Reflection.Emit.ILGenerator ... per capire come gli sguardi di codice CIL ho creato un certo codice vb.net:

Sub Main()
    Dim A As Random

    A = New Random

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

Quali ILDASM segnala come:

.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

I grado di riprodurre tutto utilizzando il metodo ILGenerator.Emit; tranne la linea ( "newobj esempio void [mscorlib] System.Random ::. ctor ()") IL_0001 ...

Speriamo che non ho travolto chiunque con troppe informazioni. Ma immagino che sia meglio essere prolisso quando si descrive un problema che sembra complesso a me.

Finalmente ho il codice che ho prodotto finora:

 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

che emette il seguente codice:

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

Le cose che ho provato già :

  • Venendo con un modo per puntare IL_Gen.Emit (OpCodes.NewObj, ... ctor ()) ... non può capire come.

  • venire con un modo per scegliere Nuovo () - dal momento che sembra essere quello .ctor () è ... Nuova non può essere utilizzato se non come un inizializzatore

  • Proprio disabilitando la funzione Random fino a quando posso venire con un modo migliore di emettere.

Il problema sembra difficile per me, ma so che c'è qualcuno là fuori che capisce la generazione di codice MSIL e più facilmente di me e che è disposto a sottolineare una risposta.

Grazie per il vostro tempo,

Dominick

È stato utile?

Soluzione

È necessario utilizzare il ConstructorInfo:

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

Inoltre - lo stoccaggio e il caricamento da quello locale sono inutili. Davvero vuole solo l'equivalente di new Random (). Avanti (100), giusto? ... nel qual caso lo stoccaggio e il caricamento da un locale non accade mai.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top