MSIL实用指南-返回结果
一个方法体执行完指令后,必须要完成调用并返回,这是要使用Ret指令。
Ret指令的详细解释是从当前方法返回,并将返回值(如果存在)从被调用方的计算堆栈推送到调用方的计算堆栈上。就是说如果计算堆栈上没有变量,则返回void类型;如果有,则返回这个栈的变量,并且这个方法的返回类型就是栈上变量的数据类型。
下面例子是返回一个整数类型
ilInstaceGenerator.Emit(OpCodes.Ldc_I4,int.MaxValue);
ilInstaceGenerator.Emit(OpCodes.Ret);
完整的程序如下:
using System;
using System.Reflection;
using System.Reflection.Emit; namespace LX1_ILDemo
{
class Demo10_Ret
{
static string binaryName = "Demo10_Ret.exe";
static string namespaceName = "LX1_ILDemo";
static string typeName = "RetTest"; static AssemblyBuilder assemblyBuilder;
static ModuleBuilder moduleBuilder;
static TypeBuilder typeBuilder;
static MethodBuilder mainMethod;
static MethodBuilder GetMaxValueMethod;
static ConstructorBuilder constructorBuilder; static void Emit_GetMaxValue()
{
GetMaxValueMethod = typeBuilder.DefineMethod("GetMaxValue", MethodAttributes.Public | MethodAttributes.Static,
typeof(int), new Type[] { });
ILGenerator ilInstaceGenerator = GetMaxValueMethod.GetILGenerator();
ilInstaceGenerator.Emit(OpCodes.Ldc_I4,int.MaxValue);
ilInstaceGenerator.Emit(OpCodes.Ret);
} public static void Generate()
{
InitAssembly();
typeBuilder = moduleBuilder.DefineType( namespaceName+"."+ typeName, TypeAttributes.Public);
constructorBuilder = typeBuilder.DefineDefaultConstructor( MethodAttributes.Public);
Emit_GetMaxValue();
EmitMain(); /* 设置assembly入口方法 */
assemblyBuilder.SetEntryPoint(mainMethod, PEFileKinds.ConsoleApplication);
SaveAssembly();
Console.WriteLine("生成成功");
} static void EmitMain()
{
mainMethod = typeBuilder.DefineMethod("Main", MethodAttributes.Public
| MethodAttributes.Static, typeof(void), new Type[] { });
ILGenerator mainILGenerator = mainMethod.GetILGenerator(); mainILGenerator.Emit(OpCodes.Call, GetMaxValueMethod);
mainILGenerator.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int) })); MethodInfo readKeyMethod = typeof(Console).GetMethod("ReadKey", new Type[] { });
mainILGenerator.Emit(OpCodes.Call, readKeyMethod);
mainILGenerator.Emit(OpCodes.Pop);
mainILGenerator.Emit(OpCodes.Ret); } 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);
}
}
}
MSIL实用指南-返回结果的更多相关文章
- MSIL实用指南-Action的生成和调用
MSIL实用指南-Action的生成和调用 System.Action用于封装一个没有参数没有返回值的方法.这里生成需要Ldftn指令. 下面讲解怎生成如下的程序. class ActionTest ...
- MSIL实用指南-生成索引器
MSIL实用指南-生成索引器 索引器是一种特殊的属性,它有参数的,也有get和set方法,属性名称一般是"Item",并且方法名称一般名称是"get_Item" ...
- MSIL实用指南-创建字段
本篇讲解怎么创建字段,主要是在修饰符的创建上. 创建字段的方法是TypeBuilder.DefineField,传入字段名称.字段类型.字段修饰符等参数,返回一个FieldBuilder对象.先看这一 ...
- MSIL实用指南-创建方法和定义参数
本篇讲解实现创建方法.指定参数的名称.实现参数加out和ref修饰符.以及参数加默认值. 创建方法 创建方法用类TypeAttributes的 DefineMethod(string name, Me ...
- MSIL实用指南-生成属性
本篇讲解怎么生成属性,包括get和set方法. 第一步,生成一个字段生成字段用TypeBuilder.DefineField方法.实例代码: FieldBuilder customerNameBldr ...
- MSIL实用指南-生成构造函数
本篇讲解生成构造函数的一些知识,包括创建实例构造函数.静态构造函数.调用父类构造函数. 生成构造函数的方法生成构造函数的方法是TypeBuilder.DefineConstructor(MethodA ...
- MSIL实用指南-闭包的生成和调用
闭包(Closure)是词法闭包(Lexical Closure)的简称.对闭包的具体定义有很多种说法,这些说法大体可以分为两类: 一种说法认为闭包是符合一定条件的函数,比如参考资源中这样定义闭包:闭 ...
- MSIL实用指南-生成异常处理
本篇讲解怎么生成异常.C# 异常处理时建立在四个关键词之上的:try.catch.finally 和 throw. 一.异常的抛出抛出异常在C#语言中要使用throw关键字,使用方法是throw &l ...
- MSIL实用指南-IL版hello world
我们学习编程开始时,一般用输出"hello world"的一段程序. C#版的"hello world"是 using System; namespace L0 ...
随机推荐
- PHP ErrorException 积累
ErrorException [不定时更新] ErrorException1: Undefined index: allocate 描述:PHP默认会对未声明变量进行提示,这种默认的提示是可以进行忽略 ...
- Spring Boot中自定义注解+AOP实现主备库切换
摘要: 本篇文章的场景是做调度中心和监控中心时的需求,后端使用TDDL实现分表分库,需求:实现关键业务的查询监控,当用Mybatis查询数据时需要从主库切换到备库或者直接连到备库上查询,从而减小主库的 ...
- mysql中left join right join inner join用法分析
mysql数据库中的关联查询,基本都会用到left join,right join,inner join等查询方式,今天来说说这三种用法的区别 1.创建表test1,test2,插入测试数据 #创建表 ...
- 夯实Java基础(十一)——内部类
1.内部类的概念 内部类顾名思义:将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类.对于很多Java初学者来说,内部类学起来真的是一头雾水,根本理解不清楚是个什么东西,包括我自己(我太菜 ...
- Unity经典游戏教程之:是男人就下100层
版权声明: 本文原创发布于博客园"优梦创客"的博客空间(网址:http://www.cnblogs.com/raymondking123/)以及微信公众号"优梦创客&qu ...
- AndroidSDK的目录详解
Tools 目录工具(必须的工具) Android SDK Tools(必须,只需下载一个版本,一般选最新版本):基础工具包,版本号带rc字样的是预览版. Android SDK Platform-t ...
- spring-boot项目的docker集成化部署(一)
目录 spring-boot项目的docker集成化部署 前言 基本思路与方案 基本步骤 准备源码 服务器和基础环境 结语 1. 本文总结: 2. 后期优化: spring-boot项目的docker ...
- 闯荡Ext-第一篇
今天在网上找到了一本非常好的书:<Ext江湖>,这本书是由大漠穷秋大神写的,刚看到这本书的时候,心里面的那个激动劲啊,本来原先的时候心里面就一直念叨着想要学习Ext,但是苦于找不到好的资料 ...
- excel 导入 下载模板 demo
import org.apache.commons.beanutils.PropertyUtils;import org.apache.commons.lang3.StringUtils;import ...
- JVM实战---类加载的过程
任何程序都需要加载到内存才能与CPU进行交流 同理, 字节码.class文件同样需要加载到内存中,才可以实例化类 ClassLoader的使命就是提前加载.class 类文件到内存中 在加载类时,使用 ...