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 <指令> <值 ...
随机推荐
- Django使用Celery异步任务队列
1 Celery简介 Celery是异步任务队列,可以独立于主进程运行,在主进程退出后,也不影响队列中的任务执行. 任务执行异常退出,重新启动后,会继续执行队列中的其他任务,同时可以缓存停止期间接收 ...
- 【Webpack的使用指南 01】Webpack入门
使用Webpack有一段时间了,但是感觉之前学的用的都比较零散,所以在这里整理一下Webpack的使用知识,从入门到进阶. 创建项目 首先创建最简单的一个项目 npm init 得到以下项目结构: 安 ...
- angular何时触发脏检查机制
ng只有在指定事件触发后,才进入$digest cycle: DOM事件,譬如用户输入文本,点击按钮等.(ng-click) XHR响应事件 ($http) 浏览器Location变更事件 ($loc ...
- 关于Android SDK Manager无法更新的解决办法
网上其实也提供了很多的解决方法,但是很多方法下载已经失效了,这里我提供一个解决方法: 1.打开SDK Manager,点击Tools-Options... 2.做如下修改: (这张图片是参考其他网站的 ...
- Beagle X15 版本制作和烧录
作为一大硬件开源组织中的一员,Beagle X15以他的强悍的性能在工业界有着广泛的应用,最近在做一个项目中 要用到它,就做了一些这方便的研究,发现里面还有不少坑要踩的,梳理一下踩到的坑,为后续做个积 ...
- MapReduce浅析
很早之前就用过Hadoop,但对MapReduce中的具体数据流向过程一直不甚明了,用Python Streamming的方式写了几个MapReduce,对这个过程有了一定的认识. 首先我们知道,Ma ...
- 自动安装L2tp的脚本
来自于 https://teddysun.com/448.html #!/usr/bin/env bash PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/ ...
- 如何关闭常见浏览器的 HSTS 功能
在安装配置 SSL 证书时,可以使用一种能使数据传输更加安全的Web安全协议,即在服务器端上开启HSTS (HTTP Strict Transport Security).它告诉浏览器只能通过HTTP ...
- memcache搭建
memcache搭建步骤: 个人原创,允许转载,请注明出处,作者,否则追究法律责任. 0.1 memcache的服务端0.2 mysql的服务端0.3 memcache 的客户端:lamp架构 1,环 ...
- [C#].Net Core下全局自定义身份过滤器使用AllowAnonymous属性
假设一种情况:项目中需要做认证和权限控制,而且需要权限才能访问的控制器要远多于可以匿名访问的(类似AO系统那样,登陆了才能用). 那在每个控制器上加一个 [Authorize] 是能解决问题,反正正我 ...