Здравствуйте, 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();
}