Использование System.reflect.emit.ilgenerator для вызова случайного в vb.net?
-
26-10-2019 - |
Вопрос
Я генерирую вывод для исполняемого файла .NET с моего собственного языка ... OpCode (называемый «случайный»), который переводится с моего языка, должен создавать случайное число в определенном диапазоне.
Цель моего кода состоит в том, чтобы произвести случайное число с помощью system.reflect.emit.ilgenerator класс ... Чтобы понять, как выглядит код CIL, я создал код VB.Net:
Sub Main()
Dim A As Random
A = New Random
Console.WriteLine(A.Next(100))
End Sub
Который Ildasm сообщает как:
.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
Я могу воспроизводить все, используя метод ilgenerator.emit; За исключением строки il_0001 ("Newobj ancement void [mscorlib] system.random ::. ctor ()") ...
Надеюсь, я никого не перегружен слишком большой информацией. Но я полагаю, что лучше быть многословным при описании проблемы, которая кажется мне сложной.
Наконец -то у меня есть код, который я создал до сих пор:
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
Который излучает следующий код:
.
.
.
IL_0073: newobj [mscorlib]System.Random
IL_0078: stloc.2
IL_0079: ldloc.2
IL_007a: callvirt instance int32 [mscorlib]System.Random::Next(int32)
.
.
.
Вещи, которые я уже пробовал:
Придумать способ указать il_gen.emit (opcodes.newobj, ... ctor ()) ... не могу понять, как.
Придумать способ указать на новый () - так как это кажется, что .ctor () ... новое не может использоваться как что -либо, кроме инициализатора.
Просто отключив случайную функцию, пока я не смогу придумать лучший способ излучения.
Проблема кажется мне сложной, но я знаю, что есть кто -то, кто понимает генерацию кода и MSIL легче, чем я, и кто готов указать на ответ.
Спасибо за ваше время,
Доминик
Решение
Вам нужно использовать ConstructorInfo:
m_ILGen.Emit(OpCodes.Newobj, GetType(Random).GetConstructor(Type.EmptyTypes))
Также - хранение и загрузка с локальной, ненужную. Вы действительно просто хотите эквивалент New Random (). Далее (100), верно? ... в каком случае хранение и загрузка с локальной.