博客园对markdown支持不佳,错乱移步Github IO 博文

CLR 的执行模型

模块/程序集

1.模块

托管模块组成部分

  • PE32/PE32+头 : PE即Portable Executable表示可执行文件
  • CLR头 : 包含所需的CLR版本,Main方法入口
  • 元数据 : 元数据是一组数据表.其中的一些数据表描述了模块中定义的内容,比如类型或成员。还有一些描述了托管模块引用的内容,比如导入的类型、成员。
  • IL代码

元数据用途

  1. 用于编译,消除了C/CPP时期对头文件的依赖
  2. VS IntelliSense,VS读取程序集的元数据,提供代码提示
  3. 允许垃圾回收器追踪对象的生存期,CLR GC采用的是Mark-Sweep形式,在mark阶段,元数据可以提供某一对象的某一字段引用了哪个其他的对象,可以把引用的对象也mark一下,防止被GC回收

2.程序集

程序集是一个或多个模块/资源 文件的逻辑分组。程序集是重用、安全性、以及版本控制的最小单元。一般认为一个dll/exe是一个程序集,但是还可以生成多文件程序集,使用AL.exe

如何判断是否安装了.NET Framework,只需检查%SystemRoot%\System32\MSCorEE.dll文件即可

如图,文件说明写出是 .NET Runtime Execution Engine

执行程序集中的代码 JIT

当一个方法第一次执行时,CLR内部的某个表会为该方法所在类型的所有方法创建一个记录项,对应着一个地址,在JIT编译IL => Native code时查找IL代码,JIT编译好的Native Code存放在内存中,并更新表中的地址,也就是下一次调用该方法时,直接执行的是Native Code,不用再次经过JIT了。这个不用是在一个程序的执行时间内,要是将程序关闭了,再打开还得重来。.NET都是半解释性性语言。

CTS : 通用类型系统

CLS : 通用语言规范

由于各个语言实现的不尽一致,MS定义了一个公共语言规范(Common Language Specification),它详细定义了一个最小功能集.

例如使用[assembly:CLSCompliant(tue)]指定此程序集是CLS兼容的

public UInt32 Abc()
public int Xyz()
public int xyz()

以上会得到警告,因为有的语言没有unsigned int,而Xyz和xyz方法,是依靠大小写来区分的,像VB 就不能区分这两个方法.

在CLS中,类型的成员要么是一个字段,要么是一个方法,像是C#提供的属性(Property),事件(event)/委托(delegate)/运算符重载 都是C#编译器提供的,到IL层,只有字段和方法.delegate会变成一个类,这个另说.

程序集生成/打包/部署

csc.exe csharp compiler

class Hello
{
public static void Main()
{
System.Console.WriteLine("Hello World ...");
}
}

csc /out:hello.exe /target:exe hello.cs

  • /out表示 输出文件
  • /target 或者 /t 表示输出类型
    1. exe 表示CUI,控制台窗口
    2. winexe GUI应用程序
    3. library 生成dll
    4. module 生成.netmodule模块,/addmodule:添加module引用
  • /reference: 或 /r 表示添加引用

csc hello.cs会生成hello.exe

/out:hello.exe 和 /t:exe 是默认的

CSC编译时默认引用MSCorLib.dll,可以指定/nostdlib使程序不默认引用这个

响应文件(.rsp)

在CSC编译的时候,/r /t /out 命令可以保存在一个文件了,如MyProj.rsp

csc @MyProj.rsp hello.cs

还会在CSC.exe 相同目录中查找一个全局的CSC.rsp文件,例如我的电脑上是C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.rsp里面Reference了一堆基本的dll,使用/noconfig指定编译时忽略这个全局响应文件

使用/r:xxx.dll来引用一个dll时,查找路径为

  1. 工作目录,当前目录
  2. CSC.exe所在目录,MSCorLib.dll从这个文件获取
  3. /lib编译时指定 or LIB环境变量

将模块合并成程序集

hello.cs

class Hello
{
public static void Main()
{
System.Console.WriteLine("Hello World ...");
Method.AStaticMethod();
}
}

method.cs

public class Method
{
public static void AStaticMethod()
{
System.Console.WriteLine("Hello from another module ...");
}
}

执行

csc /t:module method.cs
csc /addmodule:method.netmodule hello.cs
hello

结果



生成的netmodule文件是一个不包含清单元数据表的PE文件,添加到一个程序集后,这个netmodule不能删除,删除会抛出FileNotFoundException

未经处理的异常:  System.IO.FileNotFoundException: 未能加载文件或程序集“method.n
etmodule”或它的某一个依赖项。系统找不到指定的文件。 ---> System.IO.FileNotFound
Exception: 系统找不到指定的文件。 (异常来自 HRESULT:0x80070002)
--- 内部异常堆栈跟踪的结尾 ---
在 Hello.Main()

使用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中配置

<configuration>
<runtime>
<assemblyBinding>
<probing privatePath="Private"
...

强命名程序集

sn -k magicdawn.snk //创建一个snk,包含私钥公钥
csc /keyfile:magicdawn.snk hello.cs

或者

sn -p magicdawn.snk magicdawn.PublicKey //创建两个,publickey只包含公钥
sn -tp magicdawn.PublicKey //查看公钥

CLR via C# - CLR模型的更多相关文章

  1. 【CLR】解析CLR的托管堆和垃圾回收

    目录结构: contents structure [+] 为什么使用托管堆 从托管堆中分配资源 托管堆中的垃圾回收 垃圾回收算法 代 垃圾回收模式 垃圾回收触发条件 强制垃圾回收 监视内存 对包装了本 ...

  2. CLR基础,CLR运行过程,使用dos命令创建、编译、运行C#文件,查看IL代码

    CLR是Common Language Runtime的缩写,是.NET程序集或可执行程序运行的一个虚拟环境.CLR用于管理托管代码,但是它本身是由非托管代码编写的,并不是一个包含了托管代码的程序集, ...

  3. CLR Via C#: CLR 的执行模型

    CLR(Common Language Runtime)公共语言运行时:是一个可由多种编程语言使用的“运行时”. 编译源代码文件的过程: C# 源代码文件 -> C# 编译器->托管模块( ...

  4. 【深入理解CLR】1:CLR的执行模型

    将源代码编译成托管模块 下图展示了编译源代码文件的过程.如图所示,可用支持 CLR 的任何一种语言创建源代码文件.然后,用一个对应的编译器检查语法和分析源代码.无论选用哪一个编译器,结果都是一个托管模 ...

  5. 初入 CLR - 阅读《CLR via C#》笔记

    最近买了一本书<CLR via C#>阅读了第一章 - CLR 的执行模型,对 .NET 一直提到的 CLR 和 .NET Framework 有了一个大致的了解.我理解主要体现在: ■ ...

  6. CLR via C#--------CLR的执行模式

    CLR:是一个可由多种编程语言使用的“运行时”. CLR的核心功能(比如 内存管理.程序集加载.安全性.异常处理.线程同步)可由面向CLR的所有语言使用. CLR是完全围绕类型展开的. 面向CLR的语 ...

  7. clr via c# clr寄宿和AppDomain (一)

    1 clr寄宿-----.net framework在windows平台的顶部允许.者意味着.net framework必须用windows能理解的技术来构建.所有托管模块和程序集文件必须使用wind ...

  8. Win32控制台、Win32项目、MFC项目、CLR控制台、CLR空项目、空项目区别

    转载:https://blog.csdn.net/zfmss/article/details/79244696 1.Win32控制台 初始代码模版以main为程序入口,默认情况下,只链接C++运行时库 ...

  9. [Clr via C#读书笔记]Cp1CLR执行模型

    Cp1CLR执行模型 本章的概念点 CLR=Common Language Runtime 内存管理,程序集加载,安全性,异常处理和线程同步.CLR是基础,支持着面向它的各种语言.各种语言会被对应的编 ...

随机推荐

  1. 初识数据字典【weber出品必属精品】

    数据字典结构 有两部分组成: 1. 基表:以$结尾的系统表,在创建数据库的时候,oracle自动创建的表 2. 用户可以访问的视图 数据字典的种类 DICTIONARY:简称DICT,所有的数据字典, ...

  2. Tornado模块分类和各模块之间的关系

    1. Core web framework tornado.web — 包含web框架的大部分主要功能,包含RequestHandler和Application两个重要的类 tornado.https ...

  3. Java中循环删除list中元素的方法总结

    印象中循环删除list中的元素使用for循环的方式是有问题的,但是可以使用增强的for循环,然后在今天使用的时候发现报错了,然后去科普了一下,发现这是一个误区.下面我们来一起看一下. Java中循环遍 ...

  4. 第一次碰到try-except(core python programming 2nd Edition 3.6)

    # coding: utf-8 # 使用Windows系统,首行'#!/usr/bin/env Pyton'无用,全部改为'# coding: utf-8' 'readtextfile.py -- r ...

  5. Java学习笔记--Swing用户界面组件

    很多与AWT类似. 事件处理参考:Java学习笔记--AWT事件处理 1.设计模式: 模型:存储内容视图:显示内容控制器:处理用户输入· 2. 文本输入常用组件 2.1 文本域: JLabel lab ...

  6. easyui 实现Tooltip

    $('#btnAddr').tooltip({ content: $('<div class="table"></div>'), //弹出收件地址 show ...

  7. Objective-C中release和nil的关系

    (iphone/ipad)浅谈Objective-C中release和nil的关系 分类: iPhone/iPad开发技术2011-12-09 01:40 2515人阅读 评论(4) 收藏 举报 ui ...

  8. VC-关于VC++ 6.0的那些事儿

    Microsoft Visual C++,(简称Visual C++.MSVC.VC++或VC)微软公司的C++开发工具,具有集成开发环境,可提供编辑C语言,C++以及C++/CLI等编程语言.VC+ ...

  9. LeetCode_Spiral Matrix II

    Given an integer n, generate a square matrix filled with elements from 1 to n2 in spiral order. For ...

  10. Send竞争对手:百度云一小时,QQ超大附件最多支持2G,邮件附件20M到50M不等(附国外所有storage列表)——痛点是,最大传输2G,最大容量只有3G(和微云不是一回事),转存到微云文件不能超过1G

    QQ邮箱最大可发送50M普通附件(群邮件则限制在2M).此外也可以使用超大附件功能,支持将1G的文件发往任意邮箱.QQ邮箱根据你的QQ邮箱容量的不同制定相应的接受附件限制,包括附件在内,2G用户所发送 ...