反射之人千万不能错过的 EmitHelper
2007-05-07 19:57
495 查看
微软最近貌似要在 SilverLight 和 DLR 上下狠功夫,动态语言的流行和广泛使用的趋势已经是必然,无聊的我浏览了一下DLR的源代码,一堆堆的 ILGenerator.Emit 语句映入眼帘,写过 .NET 语言编译器或者玩过 MSIL 的同学们肯定对这些东西颇为熟悉,如果你恨透了这一行行的 Emit(OpCodes....)... 那你一定要试试 BLToolkit
中的 EmitHelper
以及其他的一些 Reflection 相关的东西,下面的代码使用了 BLToolkit.Reflection.EmitHelper,啊..这才是给人读的代码啊.....
Title
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;
using BLToolkit.Reflection;
using BLToolkit.Reflection.Emit;
namespace Adrian.Reflection
{
class Program
{
static void Main(string[] args)
{
string asName = "hw.exe";
AssemblyBuilderHelper assem = new AssemblyBuilderHelper(asName);
TypeBuilderHelper type = assem.DefineType("Emit.Program", TypeAttributes.Public, t.Object);
MethodBuilderHelper add = type.DefineMethod("Add", MethodAttributes.Public | MethodAttributes.Static, t.Int32, new Type[] { t.Int32Array });
add.MethodBuilder.DefineParameter(1, ParameterAttributes.None, "nums");
EmitHelper addIL = add.Emitter;
addIL.DeclareLocal(t.Int32);
addIL.DeclareLocal(t.Int32);
Label cmp = addIL.DefineLabel();
Label end = addIL.DefineLabel();
addIL
.ldc_i4_0
.stloc_0
.ldc_i4_0
.stloc_1
.MarkLabel(cmp)
.ldloc_1
.ldarg_0
.ldlen
.conv_i4
.clt
.brfalse_s(end)
.ldloc_0
.ldarg_0
.ldloc_1
.ldelem_i4
.add
.stloc_0
.ldloc_1
.ldc_i4_1
.add
.stloc_1
.br_s(cmp)
.MarkLabel(end)
.ldloc_0
.ret();
MethodBuilderHelper main = type.DefineMethod("Main", MethodAttributes.Public | MethodAttributes.Static, t.Void, new Type[] { t.StringArray });
main.MethodBuilder.DefineParameter(1, ParameterAttributes.None, "args");
EmitHelper mainIL = main.Emitter;
mainIL.DeclareLocal(t.Int32Array);
mainIL
.ldc_i4_3
.newarr(t.Int32)
.stloc_0
.ldloc_0
.ldc_i4_0
.ldc_i4_1
.stelem_i4
.ldloc_0
.ldc_i4_1
.ldc_i4_2
.stelem_i4
.ldloc_0
.ldc_i4_2
.ldc_i4_3
.stelem_i4
.ldloc_0
.call(add)
.call(typeof(Console), "WriteLine", t.Int32)
.ret();
type.Create();
assem.AssemblyBuilder.SetEntryPoint(main, PEFileKinds.ConsoleApplication);
assem.Save();
Assembly newAs = Assembly.LoadFile(Path.GetFullPath(asName));
newAs.EntryPoint.Invoke(null, new object[] { new string[] { } });
}
}
class t
{
private static Type _int32 = typeof(Int32);
private static Type _int32Array = typeof(Int32[]);
private static Type _object = typeof(Object);
private static Type _void = typeof(void);
private static Type _string = typeof(String);
private static Type _stringArray = typeof(String[]);
public static Type StringArray
{
get { return t._stringArray; }
}
public static Type String
{
get { return t._string; }
}
public static Type Void
{
get { return t._void; }
}
public static Type Object
{
get { return t._object; }
}
public static Type Int32Array
{
get { return t._int32Array; }
}
public static Type Int32
{
get { return _int32; }
}
}
}
中间的那两段 IL 是不是很像Visual C++里的内联汇编?其实 EmitHelper 只是对 ILGenerator 以及所有的 OpCode操作进行了封装,和直接使用 ILGenerator.Emit 是完全等价的, 写起来很有点 Intellisense 的感觉。
废话不说了,BLToolkit 的主页是:http://www.bltoolkit.net/
PS: BLToolkit 是开源的
中的 EmitHelper
以及其他的一些 Reflection 相关的东西,下面的代码使用了 BLToolkit.Reflection.EmitHelper,啊..这才是给人读的代码啊.....
Title
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;
using BLToolkit.Reflection;
using BLToolkit.Reflection.Emit;
namespace Adrian.Reflection
{
class Program
{
static void Main(string[] args)
{
string asName = "hw.exe";
AssemblyBuilderHelper assem = new AssemblyBuilderHelper(asName);
TypeBuilderHelper type = assem.DefineType("Emit.Program", TypeAttributes.Public, t.Object);
MethodBuilderHelper add = type.DefineMethod("Add", MethodAttributes.Public | MethodAttributes.Static, t.Int32, new Type[] { t.Int32Array });
add.MethodBuilder.DefineParameter(1, ParameterAttributes.None, "nums");
EmitHelper addIL = add.Emitter;
addIL.DeclareLocal(t.Int32);
addIL.DeclareLocal(t.Int32);
Label cmp = addIL.DefineLabel();
Label end = addIL.DefineLabel();
addIL
.ldc_i4_0
.stloc_0
.ldc_i4_0
.stloc_1
.MarkLabel(cmp)
.ldloc_1
.ldarg_0
.ldlen
.conv_i4
.clt
.brfalse_s(end)
.ldloc_0
.ldarg_0
.ldloc_1
.ldelem_i4
.add
.stloc_0
.ldloc_1
.ldc_i4_1
.add
.stloc_1
.br_s(cmp)
.MarkLabel(end)
.ldloc_0
.ret();
MethodBuilderHelper main = type.DefineMethod("Main", MethodAttributes.Public | MethodAttributes.Static, t.Void, new Type[] { t.StringArray });
main.MethodBuilder.DefineParameter(1, ParameterAttributes.None, "args");
EmitHelper mainIL = main.Emitter;
mainIL.DeclareLocal(t.Int32Array);
mainIL
.ldc_i4_3
.newarr(t.Int32)
.stloc_0
.ldloc_0
.ldc_i4_0
.ldc_i4_1
.stelem_i4
.ldloc_0
.ldc_i4_1
.ldc_i4_2
.stelem_i4
.ldloc_0
.ldc_i4_2
.ldc_i4_3
.stelem_i4
.ldloc_0
.call(add)
.call(typeof(Console), "WriteLine", t.Int32)
.ret();
type.Create();
assem.AssemblyBuilder.SetEntryPoint(main, PEFileKinds.ConsoleApplication);
assem.Save();
Assembly newAs = Assembly.LoadFile(Path.GetFullPath(asName));
newAs.EntryPoint.Invoke(null, new object[] { new string[] { } });
}
}
class t
{
private static Type _int32 = typeof(Int32);
private static Type _int32Array = typeof(Int32[]);
private static Type _object = typeof(Object);
private static Type _void = typeof(void);
private static Type _string = typeof(String);
private static Type _stringArray = typeof(String[]);
public static Type StringArray
{
get { return t._stringArray; }
}
public static Type String
{
get { return t._string; }
}
public static Type Void
{
get { return t._void; }
}
public static Type Object
{
get { return t._object; }
}
public static Type Int32Array
{
get { return t._int32Array; }
}
public static Type Int32
{
get { return _int32; }
}
}
}
中间的那两段 IL 是不是很像Visual C++里的内联汇编?其实 EmitHelper 只是对 ILGenerator 以及所有的 OpCode操作进行了封装,和直接使用 ILGenerator.Emit 是完全等价的, 写起来很有点 Intellisense 的感觉。
废话不说了,BLToolkit 的主页是:http://www.bltoolkit.net/
PS: BLToolkit 是开源的
相关文章推荐
- fir.im Weekly - 8 个不能错过的 iOS / Android 技术分享
- 那些不能错过的Xcode插件
- 最后一波机会!!本周你最不能错过的互联网大会,VIP门票0元限时抢!
- 那些不能错过的Xcode插件
- 韩正:上海千万不能出方向性失误
- 23条养生小常识,赶紧看看吧,千万不要错过!
- 50个不能错过的高品质PSD图标素材
- 【好运开启】1元抢高配服务器,绝不能错过!
- 强力推荐!那些你不能错过的 GitHub 插件和工具
- 千万别做老板最不能容忍的三种人[z]
- F8大会不能错过的精彩看点:推新移动广告形式
- 千万不能笑,千万别笑,不能笑!我真的不是有意逗你笑的~
- 《部落冲突:皇室战争》——一款不能错过的游戏!
- 那些不能错过的Xcode插件
- 你不能错过的50个网页设计者的博客(下)
- 那些不能错过的Xcode插件
- 转[转]那些不能错过的XCode插件