首页 > 代码库 > CLR via C# - CLR模型
CLR via C# - CLR模型
博客园对markdown支持不佳,错乱移步Github IO 博文
CLR 的执行模型
模块/程序集
1.模块
托管模块组成部分
- PE32/PE32+头 : PE即Portable Executable表示可执行文件
- CLR头 : 包含所需的CLR版本,Main方法入口
- 元数据 : 元数据是一组数据表.其中的一些数据表描述了模块中定义的内容,比如类型或成员。还有一些描述了托管模块引用的内容,比如导入的类型、成员。
- IL代码
元数据用途
- 用于编译,消除了C/CPP时期对头文件的依赖
- VS IntelliSense,VS读取程序集的元数据,提供代码提示
- 允许垃圾回收器追踪对象的生存期,CLR GC采用的是Mark-Sweep形式,在mark阶段,元数据可以提供某一对象的某一字段引用了哪个其他的对象,可以把引用的对象也mark一下,防止被GC回收
2.程序集
程序集是一个或多个模块/资源 文件的逻辑分组。程序集是重用、安全性、以及版本控制的最小单元。一般认为一个dll/exe是一个程序集,但是还可以生成多文件程序集,使用AL.exe
如何判断是否安装了.NET Framework,只需检查
如图,文件说明写出是
执行程序集中的代码 JIT
当一个方法第一次执行时,CLR内部的某个表会为该方法所在类型的所有方法创建一个记录项,对应着一个地址,在JIT编译IL => Native code时查找IL代码,JIT编译好的Native Code存放在内存中,并更新表中的地址,也就是下一次调用该方法时,直接执行的是Native Code,不用再次经过JIT了。这个不用是在一个程序的执行时间内,要是将程序关闭了,再打开还得重来。.NET都是半解释性性语言。
CTS : 通用类型系统CLS : 通用语言规范 由于各个语言实现的不尽一致,MS定义了一个
例如使用
1 2 3 | public UInt32 Abc() public int Xyz() public int xyz() |
在CLS中,类型的成员要么是一个
法
程序集生成/打包/部署
csc.exe csharp compiler
1 2 3 4 5 6 7 | class Hello { public static void Main() { System.Console.WriteLine( "Hello World ..." ); } } |
:
s
CSC编译时默认引用MSCorLib.dll,可以指定
b
响应文件(.rsp)
在CSC编译的时候,/r /t /out 命令可以保存在一个文件了,如MyProj.rsp
1 | csc @MyProj.rsp hello.cs |
g
使用/r:xxx.dll来引用一个dll时,查找路径为
- 工作目录,当前目录
- CSC.exe所在目录,MSCorLib.dll从这个文件获取
- /lib编译时指定 or LIB环境变量
将模块合并成程序集
hello.cs
1 2 3 4 5 6 7 8 | class Hello { public static void Main() {<br> System.Console.WriteLine( "Hello World ..." ); Method.AStaticMethod(); } } |
1 2 3 4 5 6 7 | public class Method { public static void AStaticMethod() { System.Console.WriteLine( "Hello from another module ..." ); } } |
1 2 3 | csc /t :module method.cs csc /addmodule :method.netmodule hello.cs hello |
使用AL.exe 程序连接器
```al.exe /t:library /out:example.dll a.netmodule b.netmodule ```使用/link[resource]连接资源/resource 嵌入资源
程序集的私有部署
探测目录1. AppDir\ABC.dll 2. AppDir\ABC\ABC.dll 3. AppDir\privatePath\ABC.dll 4. AppDir\privatepath\ABC\ABC.dll
privatePath在app.config中配置```
强命名程序集
```sn -k magicdawn.snk //创建一个snk,包含私钥公钥csc /keyfile:magicdawn.snk hello.cs ```或者```sn -p magicdawn.snk magicdawn.PublicKey //创建两个,publickey只包含公钥sn -tp magicdawn.PublicKey //查看公钥```