-----------------------------------------------------------
New Message on BDOTNET
-----------------------------------------------------------
From: rags_rao
Message 1 in Discussion
Ever wondered how .net compilers work? It involves validation, parsing/lexical
analysis, mapping the instructions in the corresponding language to MSIL. The
logic/implementation of doing these tasks varies from compiler of one language to
another. What is common though is generation if assemblies itself. Classes in
System.Reflection.Emit help them in this task.
<o:p></o:p>
OKAY! I�ll stop bullshitting (not good at it anyways; not my style either). Lets get
down to some code.<o:p></o:p>
<o:p></o:p>
AssemblyBuilder asmBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly()
<o:p></o:p>
That�s how you start off (I�m not getting into different options/parameters available
for creating assemblies, modules, types & methods all this is available in MSDN/SDK
docs). The statement corresponds to .assembly directive in IL. Next you define a
module which corresponds to .module directive.
<o:p></o:p>
ModuleBuilder module = asmBulider.DefineDynamicModule()<o:p></o:p>
<o:p></o:p>
and a type (say class) in the module��..
TypeBuilder class = module.DefineType()
���.. and methods in the class
<o:p></o:p>
MethodBuilder method = class.DefineMethod();<o:p></o:p>
<o:p></o:p>
And next comes the best part method.GetILGenerator() gives u a ILGenerator and u can
start pumping IL. What if u don�t remember the opcodes? No sweat all possible opcodes
are available in Opcodes class. OpCodes plus a dot (.) and u get a list of them to
choose from.<o:p></o:p>
method.GetILGenerator().Emit(OpCodes.Ret); //that�s the smallest function one can
write<o:p></o:p>
<o:p></o:p>
After defining all the methods in the class, you can optionally assign a single method
as entry point (asmBuilder.SetEntryPoint()), if your assembly is an executable
Class.CreateType(); defines the type and you can start using it.
To save the assembly (you have to create the assembly with AssemblyBuilderAccess.Save
or AssemblyBuilderAccess.RunAndSave option) use asmBuilder.Save() method.<o:p></o:p>
<o:p></o:p>
Here is the complete source code to create a �Hello world� exe.
using System.Reflection;
using System.Reflection.Emit;
using System;
class HelloWorldEmitter
{
public static void Main()
{
AssemblyName name = new AssemblyName();
name.Name="HelloWorld";
//.assembly HelloWorld{}
AssemblyBuilder asmBuilder =
AppDomain.CurrentDomain.DefineDynamicAssembly(name,AssemblyBuilderAccess.RunAndSave);
ModuleBuilder mod = asmBuilder.DefineDynamicModule
("HelloWorld","HelloWorld.exe");//.module HelloWorld.exe
//.class private auto ansi initbeforefield Helloworld
TypeBuilder myClass = mod.DefineType("HelloWorld",TypeAttributes.AutoClass |
TypeAttributes.AnsiClass |
TypeAttributes.BeforeFieldInit,null,PackingSize.Unspecified);
//.method public hidebysig static void Main() cil managed
MethodBuilder method = myClass.DefineMethod("Main",MethodAttributes.Public |
MethodAttributes.Static | MethodAttributes.HideBySig
,CallingConventions.Standard,typeof(void),null);
ILGenerator ilGen = method.GetILGenerator();
ilGen.Emit(OpCodes.Ldstr,"Hello World"); //ldstr "Hello World"
MethodInfo writeLineInfo = typeof(System.Console).GetMethod
(
"WriteLine" ,
BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod,
null,
CallingConventions.Any | CallingConventions.VarArgs ,
new Type[] {typeof(string)},null
);
ilGen.EmitCall(OpCodes.Call,writeLineInfo,null);//call void
[mscorlib]System.Console::Write(string)
ilGen.Emit(OpCodes.Ret);//ret
asmBuilder.SetEntryPoint(method);//make .entrypoint
myClass.CreateType();
Console.WriteLine("Run before save:");
myClass.InvokeMember("Main", BindingFlags.InvokeMethod | BindingFlags.Static |
BindingFlags.Public ,null, null,null);
asmBuilder.Save("HelloWorld.exe");
Console.WriteLine("HelloWorld.exe saved...\nRun after save:");
AppDomain.CurrentDomain.ExecuteAssembly("HelloWorld.exe");
}<o:p></o:p>
Conclusion: I don�t know why anybody would want to do this, but it sure is a fun way
to get your hands wet with IL.
-----------------------------------------------------------------------------------------------------------------------------------------------------------
Do u know how pale & wanton thrillful comes death on a strange hour?
unannounced......... unplanned for.......
like a scaring overfriendly guest u've brought to bed
- Jim Morrison
-----------------------------------------------------------------------------------------------------------------------------------------------------------
Regards,
Raghunandan R.
-----------------------------------------------------------
To stop getting this e-mail, or change how often it arrives, go to your E-mail
Settings.
http://groups.msn.com/bdotnet/_emailsettings.msnw
Need help? If you've forgotten your password, please go to Passport Member Services.
http://groups.msn.com/_passportredir.msnw?ppmprop=help
For other questions or feedback, go to our Contact Us page.
http://groups.msn.com/contact
If you do not want to receive future e-mail from this MSN group, or if you received
this message by mistake, please click the "Remove" link below. On the pre-addressed
e-mail message that opens, simply click "Send". Your e-mail address will be deleted
from this group's mailing list.
mailto:[EMAIL PROTECTED]