最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

.NET 使用ILPack组件将程序集保存成dll 世界球精选

来源:博客园


【资料图】

本文介绍使用ILPack组件将程序集保存成dll

.net core 版本不再支持使用 AssemblyBuilder.Save 的方式将程序集保存成dll

具体讨论 https://github.com/dotnet/runtime/issues/15704

可以使用ILPack组件将程序集保存成dll,以下为官方案例

var assembly = Assembly.GetAssembly(t);var generator = new Lokad.ILPack.AssemblyGenerator();// for ad-hoc serializationvar bytes = generator.GenerateAssemblyBytes(assembly);// direct serialization to diskgenerator.GenerateAssembly(assembly, "/path/to/file");

实际应用

在实际应用中可以使用该组件进行对编写的动态代码进行反编译验证逻辑,以下为具体案例

  1. 首先写了一个较为复杂的IL方法
public static void CreateEscapeQuotesMethod()        {            var method = new DynamicMethod("EscapeQuotes", typeof(string), new Type[1] { typeof(string) });            IL_EscapeQuotes(method.GetILGenerator());            ILPackVerification.Save(method, IL_EscapeQuotes);            var methodDelegate = method.CreateDelegate>();            string result = (string)methodDelegate.DynamicInvoke("dafdasf");            Console.WriteLine(result);            static void IL_EscapeQuotes(ILGenerator il)            {                il.DeclareLocal(typeof(string));                var lb = il.DefineLabel();                il.Emit(OpCodes.Nop);                il.Emit(OpCodes.Ldarg_0);//将第一个参数放置到堆栈上                il.Emit(OpCodes.Ldstr, "\"");                il.Emit(OpCodes.Ldstr, "\\\"");                il.Emit(OpCodes.Call, typeof(string).GetMethod(nameof(string.Replace), new Type[2] { typeof(string), typeof(string) }));                il.Emit(OpCodes.Stloc_0);//将栈顶元素存储到本地变量0中                il.Emit(OpCodes.Br_S, lb);                il.MarkLabel(lb);                il.Emit(OpCodes.Ldloc_0);// 将本地变量表中索引为0的变量加载到堆栈中                il.Emit(OpCodes.Ret);            }        }
  1. 使用ILPack将程序集转存成dll文件
public class ILPackVerification    {        public static ModuleBuilder Builder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("ILTest.Dynamic"), AssemblyBuilderAccess.Run).DefineDynamicModule("TestDynamicModule");        public static void Save(DynamicMethod method, Action setIL)        {            var type = Builder.DefineType("ILPackVerificationClass", TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.Sealed);            var newMethod = type.DefineMethod(method.Name, method.Attributes, method.ReturnType, method.GetParameters().Select(v => v.ParameterType).ToArray());            setIL(newMethod.GetILGenerator());            Console.WriteLine("方法:" + method.Name + "开始保存...");            Save(type.CreateType());        }        public static void Save(Type type)        {            var assembly = Assembly.GetAssembly(type);            Console.WriteLine("类:" + type.Name + "开始保存...");            Save(assembly);        }        public static void Save(Assembly dynamicAssembly)        {            var generator = new Lokad.ILPack.AssemblyGenerator();            generator.GenerateAssembly(dynamicAssembly, "/dils.dll");            Console.WriteLine("DLL输出成功!");        }    }
  1. 生成dll

  2. 使用ILSpay工具查看反编译之后的代码

总结

通过以上方式能够将动态程序集保存成dll文件,再通过反编译工具查看代码的逻辑,此方式可以用来验证IL代码是否编写正确(其中一种方法)。

源码地址

https://github.com/Impartsoft/ILLesson

关键词: