我们经常在项目中引用程序集。通常情况下,一个程序集包含一个module,但一个程序集也可以包含多个module。本篇就来体验:在一个可以被编译成.exe可执行文件的.cs文件中引用多个module。
□ 创建第一个module
→在前面2篇文章中,F盘的as文件夹中存放了若干程序集等文件。→打开"VS2012开发人员命令提示",输入如下命令,最终清空了F盘的as文件夹中的所有内容→在F盘的as文件夹中创建MyFirstModule.cs,用记事本打开编写如下代码,并保存using System;
class MyFirstModule
{
public static void Hello()
{
Console.WriteLine("来自module 1的问候~");
}
}
→在"VS2012开发人员命令提示",输入如下命令,把类编译成module,按回车
→输入如下命令,发现F盘的as文件夹中多了一个MyFirstModule.netmodule文件→输入如下命令,反编译生成的module,把module的IL代码放到1.txt文件中查看,按回车→输入如下命令,打开1.txt文件// Metadata version: v4.0.30319
.assembly extern mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 4:0:0:0
}
.module MyFirstModule.netmodule
// MVID: {4403DD3C-6C5D-4AD7-AAD4-2929F36C0F4F}
.imagebase 0x10000000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
// Image base: 0x00440000
// =============== CLASS MEMBERS DECLARATION ===================
.class private auto ansi beforefieldinit MyFirstModule
extends [mscorlib]System.Object
{
.method public hidebysig static void Hello() cil managed
{
// 代码大小 13 (0xd)
.maxstack 8
IL_0000: nop
IL_0001: ldstr bytearray (65 67 EA 81 6D 00 6F 00 64 00 75 00 6C 00 65 00 // eg..m.o.d.u.l.e.
20 00 31 00 84 76 EE 95 19 50 7E 00 ) // .1..v...P~.
IL_0006: call void [mscorlib]System.Console::WriteLine(string)
IL_000b: nop
IL_000c: ret
} // end of method MyFirstModule::Hello
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// 代码大小 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ret
} // end of method MyFirstModule::.ctor
} // end of class MyFirstModule
○ .assembly extern mscorlib,说明module用到了外部的mscorlib程序集
○ .module MyFirstModule.netmodule,表示modlue的名称是MyFirstModule.netmodule○ .class...,表示module中的类
□ 创建第二个module
→在F盘的as文件夹中创建MySecondModule.cs,用记事本打开编写如下代码,并保存
using System;
class MySecondModule
{
public static void Hello()
{
Console.WriteLine("来自module 2的问候~");
}
}
→在"VS2012开发人员命令提示",输入如下命令,把类编译成module,按回车
□ 引用多个module
→在F盘的as文件夹中创建MainClass.cs,用记事本打开编写如下代码,并保存
using System;
class MainClass
{
static void Main()
{
MyFirstModule.Hello();
MySecondModule.Hello();
}
}
→输入如下命令,编译MainClass.cs,并引入2个module
→输入如下命令,运行MainClass.exe→输入如下命令,反编译MainClass.exe,把它的IL代码呈现到2.txt文件中→输入如下命令,打开2.txt文件// Metadata version: v4.0.30319
.module extern MyFirstModule.netmodule
.module extern MySecondModule.netmodule
.assembly extern mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 4:0:0:0
}
.assembly MainClass
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows.
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.file MyFirstModule.netmodule
.hash = (2F 9D 95 85 6E F4 D2 CA 50 61 C0 9F A1 58 C6 5F // /...n...Pa...X._
5D 1D 96 4B ) // ]..K
.file MySecondModule.netmodule
.hash = (28 72 47 EE 2E 76 45 AA 6B 87 17 93 6B 4F 1C 5D // (rG..vE.k...kO.]
84 D8 07 CB )
.module MainClass.exe
// MVID: {FD4741CB-DEDE-4D91-9B95-16DAF3CEB47E}
.imagebase 0x00400000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
// Image base: 0x003A0000
// =============== CLASS MEMBERS DECLARATION ===================
.class private auto ansi beforefieldinit MainClass
extends [mscorlib]System.Object
{
.method private hidebysig static void Main() cil managed
{
.entrypoint
// 代码大小 14 (0xe)
.maxstack 8
IL_0000: nop
IL_0001: call void [.module MyFirstModule.netmodule]MyFirstModule::Hello()
IL_0006: nop
IL_0007: call void [.module MySecondModule.netmodule]MySecondModule::Hello()
IL_000c: nop
IL_000d: ret
} // end of method MainClass::Main
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// 代码大小 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ret
} // end of method MainClass::.ctor
} // end of class MainClass
○ .module extern MyFirstModule.netmodule,引用了MyFirstModule这个module
○ .module extern MySecondModule.netmodule,引用了MySecondModule这个module○ .assembly extern mscorlib,引用了.NET默认程序集mscorlib○ .assembly MainClass,代表本程序集○ .module MainClass.exe,说明MainClass本身包含了一个名称为MainClass.exe的module○ .class...,表示程序集类
“C#程序集系列”包括:
参考资料:
created by Jamie King