首页 > 代码库 > C#中(dotnet) :assembly和module的不同

C#中(dotnet) :assembly和module的不同

编译成module和assembly后的IL有什么不同

同一个代码编译成不同的文件后通过反编译为IL结果如下

编译成netmodule时:

Manifest文件:
// 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 MyModule.netmodule
// MVID: {DB53EC74-CABD-4430-8651-980A2322AD17}
.imagebase 0x10000000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003       // WINDOWS_CUI
.corflags 0x00000001    //  ILONLY
// Image base: 0x074B0000


MetaInfo开头:
ScopeName : MyModule.netmodule
MVID      : {DB53EC74-CABD-4430-8651-980A2322AD17}

编译成assembly时:

Manifest文件:
// 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
}
.assembly MyAssembly
{
  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) 
  .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.
  .hash algorithm 0x00008004
  .ver 0:0:0:0
}
.module MyAssembly.exe
// MVID: {CDB21366-6AC7-4748-B06A-1B05A6391118}
.imagebase 0x00400000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003       // WINDOWS_CUI
.corflags 0x00000001    //  ILONLY
// Image base: 0x074B0000

MetaInfo开头:
ScopeName : MyAssembly.exe
MVID      : {CDB21366-6AC7-4748-B06A-1B05A6391118}

将已有模块添加到程序集中时:

将模块MyModule.netmodule加入到新建的程序集中:

编译命令:csc /target:library /addmodule:MyModule.netmodule /out:LibraryAddedModule.dll

反编译后查看结果:

Manifest内容:
// 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
}
.assembly LibraryAddedModule
{
  .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 MyModule.netmodule
    .hash = (6E B4 3E 07 6D 21 3A 22 76 56 17 19 1B EB 66 D4   // n.>.m!:"vV....f.
             E6 5B B9 E8 )                                     // .[..
.class extern public ProcessDomain.Demo
{
  .file MyModule.netmodule
  .class 0x02000003
}
.class extern public ProcessDomain.Class1
{
  .file MyModule.netmodule
  .class 0x02000004
}
.class extern public ProcessDomain.ClassStatic
{
  .file MyModule.netmodule
  .class 0x02000005
}
.module LibraryAddedModule.dll
// MVID: {FCAFC9D8-E015-472C-AEAA-E6446901A0F7}
.imagebase 0x10000000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003       // WINDOWS_CUI
.corflags 0x00000001    //  ILONLY
// Image base: 0x087F0000

MetaInfo开头:
ScopeName : LibraryAddedModule.dll
MVID      : {FCAFC9D8-E015-472C-AEAA-E6446901A0F7}

至于不同之处:

程序集比模块,多了.assembly部分,如果程序集包括了已经编译好的模块,好会有对引用模块的描述部分.file 和.class extern public

 

程序集可以由多个模块组成,模块的作用:

1 模块可以更快的启动程序集,因为并不是所有的类型都在一个文件中,模块只在需要的时候加载。

2 需要多种语言来创建一个程序集时,一个模块可以用vb编写,另一个模块用C#编写,可以把这两个模块包括在一个程序集中

C#中(dotnet) :assembly和module的不同