MSIL实用指南-一维数组的操作
本篇讲解怎么生成和操作一维数组。各种数组类型创建的步骤是一样的,但是加载和保存步骤有所不同。
一.创建数组
所有类型的一维数组创建都是一样的,分三步。
1.加载数组长度
2.生成指令 Newarr <数组成员类型>
3.保存
实例代码:
ilGenerator.Emit(OpCodes.Ldc_I4_S, (sbyte));
ilGenerator.Emit(OpCodes.Newarr, typeof(int));
ilGenerator.Emit(OpCodes.Stloc_0);
二.数组的成员保存
这里的数组类型是byte、short、int、long、float、double和其它。它们的保存到成员的步骤是相似的。
首先以int型为例,它有四步。
1.加载数组变量
2.加载索引号
3.加载值
4.生成Stelem_I4指令
实例程序:
ilGenerator.Emit(OpCodes.Ldloc_0);
ilGenerator.Emit(OpCodes.Ldc_I4_0);
ilGenerator.Emit(OpCodes.Ldc_I4, int.MaxValue);
ilGenerator.Emit(OpCodes.Stelem_I4);
其它几种类型的前三步和int类型是一样的,只有最后一步不同,它们各有各的指令,对应关系是
byte:Stelem_I1
short:Stelem_I2
int:Stelem_I4
long:Stelem_I8
float:Stelem_R4
double:Stelem_R8
其它:Stelem_Ref
三.其它类型的成员加载
加载也和保存类似。首先以int型数组为例,要分三步
1.加载数组变量
2.加载索引号
3.生成Ldelem_I4指令
实例程序:
ilGenerator.Emit(OpCodes.Ldloc_0);
ilGenerator.Emit(OpCodes.Ldc_I4_0);
ilGenerator.Emit(OpCodes.Ldelem_I4);
其它类型的第三步指令各不相同,对应关系是
byte:Ldelem_I1
short:Ldelem_I2
int:Ldelem_I4
long:Ldelem_I8
float:Ldelem_R4
double:Ldelem_R8
其它:Ldelem_Ref
完整的程序如下
using System;
using System.Reflection;
using System.Reflection.Emit; namespace LX1_ILDemo
{
public class Demo21_ArrayOne
{
static string binaryName = "Demo21_ArrayOne.dll";
static string namespaceName = "LX1_ILDemo";
static string typeName = "DemoArrayOne"; static AssemblyBuilder assemblyBuilder;
static ModuleBuilder moduleBuilder;
static TypeBuilder typeBuilder;
static MethodBuilder methodBuilder;
static ILGenerator ilGenerator;
public static void Generate()
{
InitAssembly();
typeBuilder = moduleBuilder.DefineType(namespaceName + "." + typeName, TypeAttributes.Public | TypeAttributes.Abstract); methodBuilder = typeBuilder.DefineMethod("TestArray",
MethodAttributes.Public | MethodAttributes.Static,
typeof(void), new Type[] { });
ilGenerator = methodBuilder.GetILGenerator(); LocalBuilder localBuilderv1 = ilGenerator.DeclareLocal(typeof(int[]));
LocalBuilder localBuilderv2 = ilGenerator.DeclareLocal(typeof(int));
LocalBuilder localBuilderv3 = ilGenerator.DeclareLocal(typeof(float[]));
LocalBuilder localBuilderv4 = ilGenerator.DeclareLocal(typeof(float));
LocalBuilder localBuilderv5 = ilGenerator.DeclareLocal(typeof(string[]));
LocalBuilder localBuilderv6 = ilGenerator.DeclareLocal(typeof(string)); ilGenerator.Emit(OpCodes.Nop);
Generate_IntArray();
Generate_FloatArray();
Generate_StringArray(); ilGenerator.Emit(OpCodes.Ret);
SaveAssembly();
Console.WriteLine("生成成功");
} static void Generate_IntArray()
{
ilGenerator.Emit(OpCodes.Ldc_I4_S, (sbyte));
ilGenerator.Emit(OpCodes.Newarr, typeof(int));
ilGenerator.Emit(OpCodes.Stloc_0); ilGenerator.Emit(OpCodes.Ldloc_0);
ilGenerator.Emit(OpCodes.Ldc_I4_0);
ilGenerator.Emit(OpCodes.Ldc_I4, int.MaxValue);
ilGenerator.Emit(OpCodes.Stelem_I4); ilGenerator.Emit(OpCodes.Ldloc_0);
ilGenerator.Emit(OpCodes.Ldc_I4_0);
ilGenerator.Emit(OpCodes.Ldelem_I4);
ilGenerator.Emit(OpCodes.Stloc_1);
} static void Generate_FloatArray()
{
ilGenerator.Emit(OpCodes.Ldc_I4_S, (sbyte));
ilGenerator.Emit(OpCodes.Newarr, typeof(float));
ilGenerator.Emit(OpCodes.Stloc_2); ilGenerator.Emit(OpCodes.Ldloc_2);
ilGenerator.Emit(OpCodes.Ldc_I4_0);
ilGenerator.Emit(OpCodes.Ldc_I4, float.MaxValue);
ilGenerator.Emit(OpCodes.Stelem_R4); ilGenerator.Emit(OpCodes.Ldloc_2);
ilGenerator.Emit(OpCodes.Ldc_I4_0);
ilGenerator.Emit(OpCodes.Ldelem_R4);
ilGenerator.Emit(OpCodes.Stloc_3);
} static void Generate_StringArray()
{
ilGenerator.Emit(OpCodes.Ldc_I4_S, (sbyte));
ilGenerator.Emit(OpCodes.Newarr, typeof(string));
ilGenerator.Emit(OpCodes.Stloc_S, (sbyte)); ilGenerator.Emit(OpCodes.Ldloc_S, (sbyte));
ilGenerator.Emit(OpCodes.Ldc_I4_0);
ilGenerator.Emit(OpCodes.Ldstr,"test string");
ilGenerator.Emit(OpCodes.Stelem_Ref); ilGenerator.Emit(OpCodes.Ldloc_S, (sbyte));
ilGenerator.Emit(OpCodes.Ldc_I4_0);
ilGenerator.Emit(OpCodes.Ldelem_Ref);
ilGenerator.Emit(OpCodes.Stloc_S, (sbyte));
} 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实用指南-生成索引器
MSIL实用指南-生成索引器 索引器是一种特殊的属性,它有参数的,也有get和set方法,属性名称一般是"Item",并且方法名称一般名称是"get_Item" ...
- MSIL实用指南-Action的生成和调用
MSIL实用指南-Action的生成和调用 System.Action用于封装一个没有参数没有返回值的方法.这里生成需要Ldftn指令. 下面讲解怎生成如下的程序. class ActionTest ...
- MSIL实用指南-struct的生成和操作
struct(结构)是一种值类型,用于将一组相关的信息变量组织为一个单一的变量实体.所有的结构都继承自System.ValueType类,因此是一种值类型,也就是说,struct实例分配在线程的堆栈( ...
- MSIL实用指南-装箱拆箱
本篇讲述怎样装箱拆箱.装箱和拆箱都是针对值类型而言的,装箱的性能开销远比拆箱的性能开销大. 装箱装箱指令是Box.使用格式是 ILGenerator.Emit(OpCodes.Box,<值类型& ...
- MSIL实用指南-生成foreach语句
foreach可以迭代数组或者一个集合对象.foreach语句格式是它的生成步骤是foreach (<成员> in <集合>) <循环体> 一.声明三个变量,loc ...
- MSIL实用指南-给字段、属性、方法、类、程序集加Attribute
C#编程中可以给字段.方法.类以及程序集加特性即继承于Attribute的类.这里讲解怎么在IL中给它们加上特性. 生成字段的对应的类是FieldBuilder,生成属性的对应的类是PropertyB ...
- MSIL实用指南-创建对象
创建对象用Newobj指令,它的操作是创建一个新的对象或值类型,并将对象引用的新实例到计算堆栈上.格式是Newobj <构造函数>实例: ilGenerator.Emit(OpCodes. ...
- MSIL实用指南-IL版hello world
我们学习编程开始时,一般用输出"hello world"的一段程序. C#版的"hello world"是 using System; namespace L0 ...
- MSIL实用指南-加载null、string、long、float、double等值
本篇讲述怎么加载null.string值.long值.float值.double值. 加载null不需要参数值,只要 Emit ldnull 其它几个命令要 Emit <指令> <值 ...
随机推荐
- C++通过COM接口操作PPT
一. 背景 在VS环境下,开发C++代码操作PPT,支持对PPT模板的修改.包括修改文本标签.图表.表格.满足大多数软件生成PPT报告的要求,先手工创建好PPT模板,在程序中修改模板数据. 二. 开发 ...
- golang 互斥锁和读写锁
golang 互斥锁和读写锁 golang中sync包实现了两种锁Mutex(互斥锁)和RWMutex(读写锁),其中RWMutex是基于Mutex实现的,只读锁的实现使用类似引用计数器的功能. ty ...
- NancyFX 第十一章 Bootstrapping
本章我们将深入Nancy的内部,对Nancy的内部组件进行修改和调整. 那什么是bootstrap哪?字典里是这么介绍的: 一般而言,处于引导中(bootstrapping)是在终端用户可以使用之前开 ...
- uwsgi服务启动(start)停止(stop)重新装载(reload)
1. 添加uwsgi相关文件 在之前的文章跟讲到过centos中搭建nginx+uwsgi+flask运行环境,本节就基于那一次的配置进行说明. 在www中创建uwsgi文件夹,用来存放uwsgi相关 ...
- Windows cmd命令反斜杠问题
在Windows的终端输入命令的时候,如果在命令中存在斜杠就无法执行,因为它只支持反斜杠,而在Unix系统中是支持斜杠的,这是两者的区别.所以在Windows终端下执行命令需要注意斜杠问题
- ### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is java.sql.SQLException: An attempt by a client to chec
数据库连接超时,是数据库连接时的相关配置写错,例如:数据库密码,驱动等问题
- 笔记:Spring Cloud Eureka 常用配置及说明
配置参数 默认值 说明 服务注册中心配置 Bean类:org.springframework.cloud.netflix.eureka.server.EurekaServerConfigBean ...
- 用bat文件启动mongodb
bat文件是dos下的批处理文件.批处理文件是无格式的文本文件,它包含一条或多条命令.它的文件扩展名为 .bat 或 .cmd.在命令提示下键入批处理文件的名称,或者双击该批处理文件,系统就会调用cm ...
- 利用NPOI将EXCEL转换成HTML的C#实现
领导说想做一个网页打印功能,而且模板可以自定义,我考虑了三个方案,一是打印插件,二是在线 html 编辑器,三是 excel 模板,领导建议用的是打印插件的形式,我研究了一下,一个是需要下载安装,二个 ...
- Spring Cloud简介以及版本选择
什么是SpringCloud 官方的说法就是spring Cloud 给开发者提供一套按照一定套路快速开发 分布式系统 的工具. 具体点就是Spring boot实现的微服务架构开发工具.它为微服务架 ...