标签:cache 启动过程 通过 ocr 创建 cee for 线程 pre
寄宿是指让其他应用程序(非托管代码)使用CLR的能力,比如自己用C++开发的窗体能创建CLR实例。
托管代码也能调用非托管代码
- [DllImport("kernel32.dll")]
- public static extern int WinExec(string exeName, int operType);
通常会调用win32 api,但是要查文档才知道怎么定义extern方法
CLR实际上被实现为COM服务器,可以通过CoCreateInstance
或CLRCreateInstance
(推荐)创建CLR COM服务器实例,而宿主就能使用CLR的东西。
CLRCreateInstance
在MSCorEE.dll
里面(在安装.Net Framework时被到系统目录中),他的工作决定创建哪个版本的CLR(这个dll与.Net一起安装,但却是唯一的,安装了多个版本的.Net电脑中这个dll总是最新版本)
无论是托管程序还是非托管程序,他们都会编译成PE文件(保存程序的自描述信息,比如入库函数),而托管程序开始执行时会有一条JMP指令跳转到MSCorEE.dll里,通过MSCorEE.dll的PE文件信息找到这个_CorExeMain
函数的入口地址,然后修改刚才的JMP指令要跳转的地址,从而将控制跳转到了_CorExeMain这个函数里面去。随后CLR被启动,接着根据托管程序的CLR表头找到入口地址,再跳转进去,程序开始运行
程序集逻辑容器
有点像进程,提供的数据和代码隔离,但创建的代价比真正创建进程小。
AppDomain的核心是隔离但是它还是提供了跨AppDomain访问对象的方法
假设一个情景,在AppDomain A中去访问AppDomain B的对象
- AppDomain appDomainB = AppDomain.CreateDomain("NewDomain");
- DemoClass obj;
- // 在新的应用程序域中创建对象
- obj = (DemoClass)appDomainB.CreateInstanceAndUnwrap("ClassLib", "ClassLib.DemoClass");
这里会抛出异常:"ClassLib.DemoClass"未标记为可序列化
其实这个过程叫做按值封送
,这个过程中会创建两个对象,在AppDomain B中创建一个,然后序列化成字节数组,传给AppDomain A,再反序列化成对象,这种做法要求DemoClass必须被打上可序列化特性。
还有一种封送方式叫按引用封送
,这种方式要求DemoClass派生自MarshalByRefObject
还是用上面一样的代码,这个过程本质是创建了两个对象,在AppDomain A中创建了个代理对象obj,AppDomainB也创建个对象(这是真正的对象),在B向A发送对象引用前会做以下操作:
访问对象时(这是个同步的过程),利用代理类的信息,切换线程到B,获得真正的对象,调用真正的方法
通过AppDomain.Unload方法
过程:
通过修改AppDomain的静态属性MonitoringEnabled为true来启动监视,一旦启动就不能关闭.
启动后可以读取下面4个属性
通过给AppDomain.FirstChanceException事件注册方法能在AppDomain抛异常时接到通知
这个时机是:在异常抛出后查找catch块前,FirstChanceException不能处理异常,AppDomain抛异常后会寻找catch,如果找不到则将异常抛给调用该AppDomain的AppDomain(中间有跨AppDomain传递),如果一直到线程栈顶都找不到catch块,CLR将被终止
MSCorEE.dll
紧接着启动CLR,初始化后再运行Main方法CLR via C#读书笔记 CLR寄宿和AppDomain
标签:cache 启动过程 通过 ocr 创建 cee for 线程 pre
原文地址:http://www.cnblogs.com/Recoding/p/7530792.html