打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
C# 反射之动态生成dll/exe

       这个可能应该属于反射的高级使用范围了,平常在项目中使用的人估计也不是很多。

由于使用反射的话会降低性能,比如之前用到的GetValueSetValue等之类,但是使用这种方式会大大提高效率,在这里我只想说,都直接写IL指令了,效率再低的话说不过去了。。。

在之前的文章中有写过一个将已经编译好的exe文件嵌入到资源文件中,然后在打开程序的时候释放出来且运行,嗯,这是一种比较简单的实现方式;然而在这里呢,也可以利用反射来实现这个功能,使用这种方式的话,就不需要预先写好exe程序了,可以直接生成保存到本地或者在内存中运行。

其实我对IL也不熟悉,其中关于IL代码部分也是半写半猜,emmmmm,反正我也是先写c#代码然后翻译成IL的。。。

以下代码看起来也比较简单,同时也在每一行做了注释。东西是个好东西,但是有没有必要集成到日常的项目中,就需要值得深思了,很多功能但愿不是为了用而用。

实现功能:

    • 使用反射动态生成dll/exe文件

开发环境:

开发工具:Visual Studio 2013

.NET Framework版本:4.5

实现代码:

  private void EmitIL()        {            AssemblyName assemblyName = new AssemblyName("Emit");            assemblyName.Version = new Version("1.0.0");            //定义一个可以执行和保存的程序集            //此处可以理解为向解决方案中添加了一个EmitTest的项目            var defAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
//定义模块 //关于模块的概念可参考:https://docs.microsoft.com/zh-cn/dotnet/api/system.reflection.module var defModuleBuilder = defAssembly.DefineDynamicModule("EmitModule", "Emit.dll");
//定义一个公共类 var defClassBuilder = defModuleBuilder.DefineType("EmitClass", TypeAttributes.Public);
//在类中定义一个公共方法 //实现两个整数相加 var defMethodBuilder = defClassBuilder.DefineMethod("EmitMethod", MethodAttributes.Public, typeof(Int32),//返回类型 new Type[2] { typeof(Int32), typeof(Int32) }//参数类型 );
//获取IL生成器 var il = defMethodBuilder.GetILGenerator(); #region 方法的内容 // 这里的代码如果不知道怎么写,可以直接写c#代码,然后使用ILDASM或者其他软件反编译成IL代码,参考着写就行
//定义变量,x+y会产生一个变量,所以我认为这里需要先定义一下,否则会报错。 var xy = il.DeclareLocal(typeof(int)); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldarg_2); il.Emit(OpCodes.Add); il.Emit(OpCodes.Stloc_0); il.Emit(OpCodes.Br_S, xy); il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Ret);
#endregion

//创建类的 System.Type 对象 //如Type type = typeof(Form2); Type type = defClassBuilder.CreateType();
//实例化 object Instance = Activator.CreateInstance(type);
//调用方法 //object obj = type.GetMethod("EmitMethod").Invoke(Instance, new object[2] { 1, 3 }); object obj = type.InvokeMember("EmitMethod", BindingFlags.InvokeMethod, null, Instance, new object[2] { 1, 3 }); MessageBox.Show(obj.ToString());
//保存程序集 defAssembly.Save("Emit.dll"); }
 private void btn_emit_Click(object sender, EventArgs e)        {            EmitIL();        }

实现效果:

以上代码最后会将程序集保存到本地,这里可以反编译看到生成的dll的代码如下:

由简入繁,拿来即用

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
反射发出动态类型(下)
【原创】颠覆C#王权的“魔比斯环” — 实现AOP框架的终极利器
C#通过Emit动态生成代码
.NET高级特性-Emit(1)
自己动手开发编译器(十二)生成托管代码
c# – 为什么ILGenerator将Leave指令插入Foreach语句
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服