Re: Загрузка и выполнение DynamicMethod из byte массива
От: vit_as Россия  
Дата: 15.07.13 18:00
Оценка:
Здравствуйте, qlat, Вы писали:

Q>Цель сохранить байт-код объекта DynamicMethod, и при следующем запуске программы загрузить и выполнить


Q>1. Этап получение байт-кода


Q>Пример

Q>using System.Reflection;
Q>using System.Reflection.Emit;

Q>void f()

Q>{
Q>DynamicMethod d = new DynamicMethod("xxx", typeof(void), null);

Q>ILGenerator il = d.GetILGenerator();

Q>int idx = il.DeclareLocal(typeof(string)).LocalIndex;

Q>il.Emit(OpCodes.Nop);

Q>il.Emit(OpCodes.Ldstr, "Hellow world");
Q>il.Emit(OpCodes.Stloc, idx);
Q>il.Emit(OpCodes.Ldloc, idx);

Q>Type[] t = new Type [1] { typeof(string) };


Q>MethodInfo mi = typeof(Console).GetMethod("WriteLine", t );

Q>Console.WriteLine(mi.MetadataToken.ToString());

Q>il.Emit(OpCodes.Call, mi);

Q>il.Emit(OpCodes.Nop);
Q>mi = typeof(Console).GetMethod("ReadLine");
Q>il.Emit(OpCodes.Call, mi);
Q>il.Emit(OpCodes.Pop);
Q>il.Emit(OpCodes.Ret);

Q>MethodBody mb = d.GetMethodBody();

Q>byte[] src = mb.GetILAsByteArray();

Q>/*

Q>var ilgen = d.GetILGenerator();
Q>var fiBytes = il.GetType().BaseType.GetField("m_ILStream", BindingFlags.Instance | BindingFlags.NonPublic);
Q>var fiLength = il.GetType().BaseType.GetField("m_length", BindingFlags.Instance | BindingFlags.NonPublic);
Q>byte[] code = fiBytes.GetValue(ilgen) as byte[];
Q>int cnt = (int)fiLength.GetValue(ilgen);
Q>byte[] src = new byte[cnt];
Q>Buffer.BlockCopy(code, 0, src, 0, cnt);
Q>*/
Q>}

Q>На строке MethodBody mb = d.GetMethodBody();

Q>возникает Exception — Операция является недопустимой из-за текущего состояния объекта.
Q>Байт-код можно получить другим кодом (см. комментарии), но хочется понять, почему нельзя воспользоваться стандартным решением

Метод GetMethodBody не переопределен в классе DynamicMethod. Вызывается метод базового класса MethodBase

                 public virtual MethodBody GetMethodBody()
        {
            throw new InvalidOperationException();
        }
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.