我们学习编程开始时,一般用输出"hello world"的一段程序。

C#版的"hello world"是

using System;

namespace L01_HelloDemo
{
class HelloWorld
{
class Hello
{
public static void Main2()
{
Console.WriteLine("Hello World!");
Console.ReadKey();
}
}
}
}

用生成IL方式也可以输出"hello world",它的实现源码是

using System;
using System.Reflection;
using System.Reflection.Emit; namespace L01_HelloDemo
{
class HelloWorldILGenerator
{
static string binaryName = "ILHelloWorldDemo.exe";
static string namespaceName = "ILHelloWorldDemo";
static string typeName = "HelloWorld"; static AssemblyBuilder assemblyBuilder;
static ModuleBuilder moduleBuilder;
static TypeBuilder typeBuilder; public static void Generate()
{
InitAssembly(); /* 生成 public class HelloWorld */
typeBuilder = moduleBuilder.DefineType(typeName, TypeAttributes.Public); /* 生成 public static void Main() */
MethodBuilder mainMethod = typeBuilder.DefineMethod("Main",MethodAttributes.Public | MethodAttributes.Static, typeof(void), new Type[] { });
ILGenerator methIL = mainMethod.GetILGenerator(); /* 生成 Console.WriteLine("Hello World!"); */
MethodInfo writeLineMethod = typeof(Console).GetMethod("WriteLine",new Type[]{ typeof(string) });
methIL.Emit(OpCodes.Ldstr, "Hello World!");
methIL.Emit(OpCodes.Call, writeLineMethod); /* 生成 Console.ReadKey(); */
MethodInfo readKeyMethod = typeof(Console).GetMethod("ReadKey", new Type[] { });
methIL.Emit(OpCodes.Call, readKeyMethod);
methIL.Emit(OpCodes.Pop); methIL.Emit(OpCodes.Ret); /* 设置assembly入口方法 */
assemblyBuilder.SetEntryPoint(mainMethod, PEFileKinds.ConsoleApplication); SaveAssembly();
Console.WriteLine("生成成功");
Console.ReadKey();
} static void InitAssembly()
{
AssemblyName assemblyName = new AssemblyName(namespaceName);
assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name, binaryName);
} static void SaveAssembly()
{
Type t = typeBuilder.CreateType(); //完成Type,这是必须的
assemblyBuilder.Save(binaryName);
}
}
}

调用 HelloWorldILGenerator.Generate()后生成ILHelloWorldDemo.exe文件,打开它运行的效果和C#版的"hello world"的是一样的,

用ILSpy对ILHelloWorldDemo.exe进行反编译,反编译的源码也和和C#版的"hello world"的是一样的。

MSIL实用指南-IL版hello world的更多相关文章

  1. MSIL实用指南-生成索引器

    MSIL实用指南-生成索引器 索引器是一种特殊的属性,它有参数的,也有get和set方法,属性名称一般是"Item",并且方法名称一般名称是"get_Item" ...

  2. MSIL实用指南-Action的生成和调用

    MSIL实用指南-Action的生成和调用 System.Action用于封装一个没有参数没有返回值的方法.这里生成需要Ldftn指令. 下面讲解怎生成如下的程序. class ActionTest ...

  3. MSIL实用指南-加载bool、sbyte、byte、char、short等值

    这一篇讲解怎么加载bool值.sbyte值.byte值.char值.short值. 加载bool值在.NET程序实际运行中,是没有true和false值的,实际上是以1和0表示它们,加载它们的指令是L ...

  4. MSIL实用指南-闭包的生成和调用

    闭包(Closure)是词法闭包(Lexical Closure)的简称.对闭包的具体定义有很多种说法,这些说法大体可以分为两类: 一种说法认为闭包是符合一定条件的函数,比如参考资源中这样定义闭包:闭 ...

  5. MSIL实用指南-给字段、属性、方法、类、程序集加Attribute

    C#编程中可以给字段.方法.类以及程序集加特性即继承于Attribute的类.这里讲解怎么在IL中给它们加上特性. 生成字段的对应的类是FieldBuilder,生成属性的对应的类是PropertyB ...

  6. MSIL实用指南-比较运算

    数值的比较就是大于.小于.等于.大于等于.小于等于.不等于,它们的运算结果都是布尔值.大于.小于.等于有直接对应的指令,分别是Cgt.Clt.Ceq.大于等于.小于等于.不等于没有直接对应的指令,它的 ...

  7. MSIL实用指南-加载int值

    这一篇讲的是怎样加载整数值到运算栈上.这一类的指令都是以Ldc_I4开头. Ldc_I4类OpCodes的Ldc_I4字段的功能是把一个int值压入运算栈上.它的使用方法是ilGenerator.Em ...

  8. MSIL实用指南-加载null、string、long、float、double等值

    本篇讲述怎么加载null.string值.long值.float值.double值. 加载null不需要参数值,只要 Emit ldnull 其它几个命令要 Emit <指令> <值 ...

  9. MSIL实用指南-局部变量的声明、保存和加载

    这一篇讲解方法内的局部变量是怎么声明.怎样保存.怎样加载的. 声明局部变量声明用ILGenerator的DeclareLocal方法,参数是局部变量的数据类型,得到一个局部变量对应的创建类LocalB ...

随机推荐

  1. ecshop QQ邮箱发送邮件服务器配置

    ecshop QQ邮箱发送邮件服务器配置 1.邮件服务:采用其他的SMTP服务 2.邮件服务器是否要求加密连接(SSL): 是 此项设置需要php支持openSSL模块 开启方法: a.php.ini ...

  2. SQL查询练习一(From LeetCode)

     请选用MySQL进行测试. 1.找出后一天比前一天温度高的日期(E) 思路:将该表进行自关联,然后选择出日期靠后的一天,最后选择温度高的日期 select Weather.Id from Weath ...

  3. mysql cp复制和mysqldump备份测试

    本文来自我的github pages博客http://galengao.github.io/ 即www.gaohuirong.cn 备份策略 针对不同的场景下, 我们应该制定不同的备份策略对数据库进行 ...

  4. Python自动化--语言基础7--操作日志、加密、发送邮件、线程、生产者消费者

    1.操作日志 logging.basicConfig:日志的统一处理器,对日志的输出格式和方式做配置日志级别等级CRITICAL > ERROR > WARNING > INFO & ...

  5. JDBC 基础

    JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口 ...

  6. springmvc+mybatis+mysql 数据库插入中文是乱码

    java web项目,前台页面的表单数据,插入到数据库时,结果出现乱码"???"的问题,断断续续折腾了一天时间,废话不说,步骤如下: 一:在web.xml中配置:编码格式拦截器 & ...

  7. maven中的profile文件的解析

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...

  8. springboot2.0(一):【重磅】Spring Boot 2.0权威发布

    就在昨天Spring Boot2.0.0.RELEASE正式发布,今天早上在发布Spring Boot2.0的时候还出现一个小插曲,将Spring Boot2.0同步到Maven仓库的时候出现了错误, ...

  9. Batch Normalization&Dropout浅析

    一. Batch Normalization 对于深度神经网络,训练起来有时很难拟合,可以使用更先进的优化算法,例如:SGD+momentum.RMSProp.Adam等算法.另一种策略则是高改变网络 ...

  10. thinkpad E480 用户初体验

    梦寐以求的E480终于到手了,经过几天使用之后,也该写一下用户体验了,也算是对这些天的调研的一个总结吧. 首先是外形,从外形上来看E480的外形的确是相对以前的塑料外壳,改进了不少,全金属的机身,磨砂 ...