Кастинг Объекта к определенному классу в IL?

Ваш RTOS разработан таким способом, которым он может гарантировать синхронизации для важных событий, как аппаратное прерывание обрабатывающие и просыпающиеся ждущие процессы точно, когда они должны будут быть.

Эта точная синхронизация позволяет программисту быть уверенным, что его (говорить) кардиостимулятор собирается произвести импульс точно, когда это должно, немало десятков миллисекунд позже, потому что ОС была занята другой неэффективной задачей.

Это обычно - намного более простая ОС, чем абсолютный Linux или Windows, просто потому что легче проанализировать и предсказать поведение простого кода. Нет ничего останавливающего абсолютную ОС как Linux, используемый в среде RTOS, и он имеет расширения RTOS. Из-за сложности кодовой базы это не сможет гарантировать свои синхронизации вниз как маленький-a масштаб как меньшая ОС.

планировщик RTOS также более строг, чем планировщик общего назначения. Важно знать, что планировщик не собирается изменять Ваш приоритет задачи, потому что Вы выполняли долгое время и не имеете никаких интерактивных пользователей. Большая часть ОС уменьшила бы внутренний приоритет этого типа процесса для одобрения краткосрочных интерактивных программ, где интерфейс, как должно замечаться, не отстает.

5
задан Lasse V. Karlsen 13 October 2009 в 08:20
поделиться

1 ответ

Краткий ответ:

// Call Test method
il.Emit(OpCodes.Ldloc, variable);
il.Emit(OpCodes.Castclass, type);
il.Emit(OpCodes.Call, type.GetMethod("TestMethod"));

Но как это получить? Я использовал метод Reflector . Во-первых, напишите метод, который сделает то, что вы хотите. Я придумал следующее:

private static object PrecompiledTest()
{
    object variable = new TestClass();
    ((TestClass) variable).TestMethod();
    return variable;
}

Теперь скомпилируйте это, откройте Reflector и откройте вашу сборку. Перейдите к своей функции и найдите ее в MSIL. Вышеуказанная функция декомпилируется в следующую:

.method private hidebysig static object PrecompiledTest() cil managed
{
    .maxstack 1
    .locals init (
        [0] object variable,
        [1] object CS$1$0000)
    L_0000: nop 
    L_0001: newobj instance void EmitTest.TestClass::.ctor()
    L_0006: stloc.0 
    L_0007: ldloc.0 
    L_0008: castclass EmitTest.TestClass
    L_000d: callvirt instance void EmitTest.TestClass::TestMethod()
    L_0012: nop 
    L_0013: ldloc.0 
    L_0014: stloc.1 
    L_0015: br.s L_0017
    L_0017: ldloc.1 
    L_0018: ret 
}

Вышеупомянутая функция использует callvirt вместо call . Я не очень разбираюсь в IL, поэтому я не уверен в разнице, но call действительно работает в вашем примере. И последнее, пока мы говорим о Reflector. Вы можете использовать надстройку ReflectionEmitLanguage , чтобы сгенерировать для вас свой код Emit . Это дополнение генерирует для вас следующий код:

public MethodBuilder BuildMethodPrecompiledTest(TypeBuilder type)
{
    // Declaring method builder
    // Method attributes
    System.Reflection.MethodAttributes methodAttributes = 
          System.Reflection.MethodAttributes.Private
        | System.Reflection.MethodAttributes.HideBySig
        | System.Reflection.MethodAttributes.Static;
    MethodBuilder method = type.DefineMethod("PrecompiledTest", methodAttributes);
    // Preparing Reflection instances
    ConstructorInfo ctor1 = typeof(TestClass).GetConstructor(
        BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, 
        null, 
        new Type[]{
            }, 
        null
        );
    MethodInfo method2 = typeof(TestClass).GetMethod(
        "TestMethod", 
        BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, 
        null, 
        new Type[]{
            }, 
        null
        );
    // Setting return type
    method.SetReturnType(typeof(Object));
    // Adding parameters
    ILGenerator gen =  method.GetILGenerator();
    // Preparing locals
    LocalBuilder variable =  gen.DeclareLocal(typeof(Object));
    LocalBuilder CS$1$0000 =  gen.DeclareLocal(typeof(Object));
    // Preparing labels
    Label label23 =  gen.DefineLabel();
    // Writing body
    gen.Emit(OpCodes.Nop);
    gen.Emit(OpCodes.Newobj,ctor1);
    gen.Emit(OpCodes.Stloc_0);
    gen.Emit(OpCodes.Ldloc_0);
    gen.Emit(OpCodes.Castclass,TestClass);
    gen.Emit(OpCodes.Callvirt,method2);
    gen.Emit(OpCodes.Nop);
    gen.Emit(OpCodes.Ldloc_0);
    gen.Emit(OpCodes.Stloc_1);
    gen.Emit(OpCodes.Br_S,label23);
    gen.MarkLabel(label23);
    gen.Emit(OpCodes.Ldloc_1);
    gen.Emit(OpCodes.Ret);
    // finished
    return method;
}
12
ответ дан 13 December 2019 в 05:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: