分享
 
 
 

编程实现动态生成程序技术

王朝other·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

动态生成程序技术

DynamicProxy(无特殊说明的化,都指Castle's DynamicProxy for .net中的DynamicProxy技术)是建立在动态程序集生成技术的基础之上的,也就是说程序在运行时动态生成IL代码并被编译执行。

动态程序集生成技术 也就是说序在运行时动态生成IL代码并被编译执行

ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.2052/cpguide/html/cpconemittingdynamicassemblies.htm

动态程序集System.Reflection.Emit 命名空间中的一组托管类型,它们允许编译器或工具在运行时发出元数据和 Microsoft 中间语言 (MSIL),或者也可以允许它们在磁盘上生成可移植可执行 (PE) 文件。脚本引擎和编译器是此命名空间的主要用户。在本节中,由 System.Reflection.Emit 命名空间提供的功能称为反射发出。

反射发出提供下列服务:

在运行时定义程序集,然后运行这些程序集并/或将它们保存到磁盘。

在运行时定义新程序集中的模块,然后运行这些模块并/或将它们保存到磁盘。

在运行时定义类型,创建这些类型的实例,并调用这些类型的方法。

为定义的模块定义可由调试器和代码分析器这样的工具使用的符号信息。

如果你想了解更多内容:见System.Reflection.Emit下面

改例子来自msdn,有兴趣大家运行下

下面是一个运行的代码示例: 见文件夹TypeResolve

usingSystem;

usingSystem.Text;

usingSystem.Threading;

usingSystem.Reflection;

usingSystem.Reflection.Emit;

//手动写的类和程序与动态的程序集相同的功能

//---

//classPoint{

//

//privateintx;

//privateinty;

//

//publicPoint(intix,intiy){

//

//this.x=ix;

//this.y=iy;

//

//}

//

//publicintDotProduct(Pointp){

//

//return((this.x*p.x)+(this.y*p.y));

//

//}

//

//publicstaticvoidPointMain(){

//

//Console.Write("Enterthe'x'valueforpoint1:");

//intx1=Convert.ToInt32(Console.ReadLine());

//

//Console.Write("Enterthe'y'valueforpoint1:");

//inty1=Convert.ToInt32(Console.ReadLine());

//

//Console.Write("Enterthe'x'valueforpoint2:");

//intx2=Convert.ToInt32(Console.ReadLine());

//

//Console.Write("Enterthe'y'valueforpoint2:");

//inty2=Convert.ToInt32(Console.ReadLine());

//

//Pointp1=newPoint(x1,y1);

//Pointp2=newPoint(x2,y2);

//

//Console.WriteLine("({0},{1}).({2},{3})={4}.",

//x1,y1,x2,y2,p1.DotProduct(p2));

//

//}

//

//}

//---

classAssemblyBuilderDemo

{

publicstaticTypeBuildDynAssembly()

{

//声明类型

TypepointType=null;

//类型所在应用域

AppDomaincurrentDom=Thread.GetDomain();

//为你动态生成的程序集合输入名称

Console.Write("Pleaseenteranameforyournewassembly:");

StringBuilderasmFileNameBldr=newStringBuilder();

asmFileNameBldr.Append(Console.ReadLine());

asmFileNameBldr.Append(".exe");

stringasmFileName=asmFileNameBldr.ToString();

AssemblyNamemyAsmName=newAssemblyName();

myAsmName.Name="MyDynamicAssembly";

//定义程序集

AssemblyBuildermyAsmBldr=currentDom.DefineDynamicAssembly(

myAsmName,

AssemblyBuilderAccess.RunAndSave);

//

//withinittoreflectthetypePointinto.

//定义模块

ModuleBuildermyModuleBldr=myAsmBldr.DefineDynamicModule(asmFileName,

asmFileName);

//定义类名

TypeBuildermyTypeBldr=myModuleBldr.DefineType("Point");

//定义个类属性

FieldBuilderxField=myTypeBldr.DefineField("x",typeof(int),

FieldAttributes.Private);

FieldBuilderyField=myTypeBldr.DefineField("y",typeof(int),

FieldAttributes.Private);

//定义构造函数

TypeobjType=Type.GetType("System.Object");

ConstructorInfoobjCtor=objType.GetConstructor(newType[0]);

//定义参数

Type[]ctorParams=newType[]
{typeof(int),typeof(int)};

ConstructorBuilderpointCtor=myTypeBldr.DefineConstructor(

MethodAttributes.Public,

CallingConventions.Standard,

ctorParams);

ILGeneratorctorIL=pointCtor.GetILGenerator();

ctorIL.Emit(OpCodes.Ldarg_0);

ctorIL.Emit(OpCodes.Call,objCtor);

ctorIL.Emit(OpCodes.Ldarg_0);

ctorIL.Emit(OpCodes.Ldarg_1);

ctorIL.Emit(OpCodes.Stfld,xField);

ctorIL.Emit(OpCodes.Ldarg_0);

ctorIL.Emit(OpCodes.Ldarg_2);

ctorIL.Emit(OpCodes.Stfld,yField);

ctorIL.Emit(OpCodes.Ret);

//定义DotProduct方法

MethodBuilderpointDPBldr=myTypeBldr.DefineMethod("DotProduct",

MethodAttributes.Public,

typeof(int),

newType[]
{myTypeBldr});

ILGeneratordpIL=pointDPBldr.GetILGenerator();

dpIL.Emit(OpCodes.Ldarg_0);

dpIL.Emit(OpCodes.Ldfld,xField);

dpIL.Emit(OpCodes.Ldarg_1);

dpIL.Emit(OpCodes.Ldfld,xField);

dpIL.Emit(OpCodes.Mul_Ovf_Un);

dpIL.Emit(OpCodes.Ldarg_0);

dpIL.Emit(OpCodes.Ldfld,yField);

dpIL.Emit(OpCodes.Ldarg_1);

dpIL.Emit(OpCodes.Ldfld,yField);

dpIL.Emit(OpCodes.Mul_Ovf_Un);

dpIL.Emit(OpCodes.Add_Ovf_Un);

dpIL.Emit(OpCodes.Ret);

//定义PointMain()方法

Console.WriteLine("DotProductbuilt.");

MethodBuilderpointMainBldr=myTypeBldr.DefineMethod("PointMain",

MethodAttributes.Public|

MethodAttributes.Static,

typeof(void),

null);

pointMainBldr.InitLocals=true;

ILGeneratorpmIL=pointMainBldr.GetILGenerator();

//我们调用四个方法

//MethodInfotokens:

//-voidConsole.WriteLine(string)

//-stringConsole.ReadLine()

//-intConvert.Int32(string)

//-voidConsole.WriteLine(string,object[])

MethodInfowriteMI=typeof(Console).GetMethod(

"Write",

newType[]
{typeof(string)});

MethodInforeadLineMI=typeof(Console).GetMethod(

"ReadLine",

newType[0]);

MethodInfoconvertInt32MI=typeof(Convert).GetMethod(

"ToInt32",

newType[]
{typeof(string)});

Type[]wlParams=newType[]
{typeof(string),typeof(object[])};

MethodInfowriteLineMI=typeof(Console).GetMethod(

"WriteLine",

wlParams);

//Althoughwecouldjustrefertothelocalvariablesby

//index(shortintsforLdloc/Stloc,bytesforLdLoc_S/Stloc_S),

//thistime,we'lluseLocalBuildersforclarityandto

//demonstratetheirusageandsyntax.

//定义四个局部变量

LocalBuilderx1LB=pmIL.DeclareLocal(typeof(int));

LocalBuildery1LB=pmIL.DeclareLocal(typeof(int));

LocalBuilderx2LB=pmIL.DeclareLocal(typeof(int));

LocalBuildery2LB=pmIL.DeclareLocal(typeof(int));

//定义两个动态类型的举办变量

LocalBuilderpoint1LB=pmIL.DeclareLocal(myTypeBldr);

LocalBuilderpoint2LB=pmIL.DeclareLocal(myTypeBldr);

LocalBuildertempObjArrLB=pmIL.DeclareLocal(typeof(object[]));

//完成

//Console.Write("Enterthe'x'valueforpoint1:");

//intx1=Convert.ToInt32(Console.ReadLine());

pmIL.Emit(OpCodes.Ldstr,"Enterthe'x'valueforpoint1:");

pmIL.EmitCall(OpCodes.Call,writeMI,null);

pmIL.EmitCall(OpCodes.Call,readLineMI,null);

pmIL.EmitCall(OpCodes.Call,convertInt32MI,null);

pmIL.Emit(OpCodes.Stloc,x1LB);

//完成

//Console.Write("Enterthe'y'valueforpoint1:");

//inty1=Convert.ToInt32(Console.ReadLine());

pmIL.Emit(OpCodes.Ldstr,"Enterthe'y'valueforpoint1:");

pmIL.EmitCall(OpCodes.Call,writeMI,null);

pmIL.EmitCall(OpCodes.Call,readLineMI,null);

pmIL.EmitCall(OpCodes.Call,convertInt32MI,null);

pmIL.Emit(OpCodes.Stloc,y1LB);

//Console.Write("Enterthe'x'valueforpoint2:");

//intx2=Convert.ToInt32(Console.ReadLine());

pmIL.Emit(OpCodes.Ldstr,"Enterthe'x'valueforpoint2:");

pmIL.EmitCall(OpCodes.Call,writeMI,null);

pmIL.EmitCall(OpCodes.Call,readLineMI,null);

pmIL.EmitCall(OpCodes.Call,convertInt32MI,null);

pmIL.Emit(OpCodes.Stloc,x2LB);

//Console.Write("Enterthe'y'valueforpoint2:");

//inty2=Convert.ToInt32(Console.ReadLine());

pmIL.Emit(OpCodes.Ldstr,"Enterthe'y'valueforpoint2:");

pmIL.EmitCall(OpCodes.Call,writeMI,null);

pmIL.EmitCall(OpCodes.Call,readLineMI,null);

pmIL.EmitCall(OpCodes.Call,convertInt32MI,null);

pmIL.Emit(OpCodes.Stloc,y2LB);

//Pointp1=newPoint(x1,y1);

pmIL.Emit(OpCodes.Ldloc,x1LB);

pmIL.Emit(OpCodes.Ldloc,y1LB);

pmIL.Emit(OpCodes.Newobj,pointCtor);

pmIL.Emit(OpCodes.Stloc,point1LB);

//Pointp2=newPoint(x2,y2);

pmIL.Emit(OpCodes.Ldloc,x2LB);

pmIL.Emit(OpCodes.Ldloc,y2LB);

pmIL.Emit(OpCodes.Newobj,pointCtor);

pmIL.Emit(OpCodes.Stloc,point2LB);

完成计算#region完成计算

//Console.WriteLine("({0},{1}).({2},{3})={4}.",

//x1,y1,x2,y2,p1.DotProduct(p2));

//

pmIL.Emit(OpCodes.Ldstr,"({0},{1}).({2},{3})={4}.");

pmIL.Emit(OpCodes.Ldc_I4_5);

pmIL.Emit(OpCodes.Newarr,typeof(Object));

pmIL.Emit(OpCodes.Stloc,tempObjArrLB);

pmIL.Emit(OpCodes.Ldloc,tempObjArrLB);

pmIL.Emit(OpCodes.Ldc_I4_0);

pmIL.Emit(OpCodes.Ldloc,x1LB);

pmIL.Emit(OpCodes.Box,typeof(int));

pmIL.Emit(OpCodes.Stelem_Ref);

pmIL.Emit(OpCodes.Ldloc,tempObjArrLB);

pmIL.Emit(OpCodes.Ldc_I4_1);

pmIL.Emit(OpCodes.Ldloc,y1LB);

pmIL.Emit(OpCodes.Box,typeof(int));

pmIL.Emit(OpCodes.Stelem_Ref);

pmIL.Emit(OpCodes.Ldloc,tempObjArrLB);

pmIL.Emit(OpCodes.Ldc_I4_2);

pmIL.Emit(OpCodes.Ldloc,x2LB);

pmIL.Emit(OpCodes.Box,typeof(int));

pmIL.Emit(OpCodes.Stelem_Ref);

pmIL.Emit(OpCodes.Ldloc,tempObjArrLB);

pmIL.Emit(OpCodes.Ldc_I4_3);

pmIL.Emit(OpCodes.Ldloc,y2LB);

pmIL.Emit(OpCodes.Box,typeof(int));

pmIL.Emit(OpCodes.Stelem_Ref);

pmIL.Emit(OpCodes.Ldloc,tempObjArrLB);

pmIL.Emit(OpCodes.Ldc_I4_4);

pmIL.Emit(OpCodes.Ldloc,point1LB);

pmIL.Emit(OpCodes.Ldloc,point2LB);

pmIL.EmitCall(OpCodes.Callvirt,pointDPBldr,null);

pmIL.Emit(OpCodes.Box,typeof(int));

pmIL.Emit(OpCodes.Stelem_Ref);

pmIL.Emit(OpCodes.Ldloc,tempObjArrLB);

pmIL.EmitCall(OpCodes.Call,writeLineMI,null);

#endregion

//结束

pmIL.Emit(OpCodes.Ret);

Console.WriteLine("PointMain(entrypoint)built.");

pointType=myTypeBldr.CreateType();

Console.WriteLine("Typebaked.");

myAsmBldr.SetEntryPoint(pointMainBldr);

myAsmBldr.Save(asmFileName);

Console.WriteLine("Assemblysavedas'{0}'.",asmFileName);

Console.WriteLine("Type'{0}'attheprompttorunyournew"+

"dynamicallygenerateddotproductcalculator.",

asmFileName);

//Afterexecution,thisprogramwillhavegeneratedandwrittentodisk,

//inthedirectoryyouexecuteditfrom,aprogramnamed

//<name_you_entered_here>.exe.Youcanrunitbytyping

//thenameyougaveitduringexecution,inthesamedirectorywhere

//youexecutedthisprogram.

returnpointType;

}

publicstaticvoidMain()

{

TypemyType=BuildDynAssembly();

Console.WriteLine("---");

//Let'sinvokethetype'Point'createdinourdynamicassembly.

objectptInstance=Activator.CreateInstance(myType,newobject[]
{0,0});

myType.InvokeMember("PointMain",

BindingFlags.InvokeMethod,

null,

ptInstance,

newobject[0]);

Console.ReadLine();

}

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有