我一直在使用.net开发应用程序已有一段时间了.但是,我仍然不确定CLR是如何知道.net应用程序已经启动的.是否每个应用程序都有一个CLR实例?我不认为这可能是这种情况,因为只有一个GC管理所有.net应用程序的所有内存.CLR是否在后台运行?我很困惑.
mem*_*ech 43
嗯,让我来看看这个.
有人用C#或.NET"中间语言"或其他托管语言构建.NET应用程序.
该语言的编译器csc.exe(C#)或ilasm.exe(字节码汇编程序)或其中任何一个生成PE可执行文件.PE可执行文件具有编译器或汇编程序填充的特定结构.那包括:
单击可执行文件,从命令行运行或从Win32 API执行时,Windows加载程序实现(在NTDLL.dll中)接管
加载程序代码负责将可执行文件存入内存,根据需要加载动态链接库,将链接库映射到可执行代码可以访问它们的位置,以及使用映射库的实际地址更新导入地址表.
一旦准备就绪,加载器就会跳转到入口点(通过我假设的一些恶作剧从内核空间切换到用户空间,或者转换到保护模式,因为应用程序在它自己的受保护的32位或64位内存空间中运行).入口点是mscoree.dll - .NET公共对象运行时执行引擎,它刚刚映射到进程内存中.我已经看到这个DLL被称为.NET启动垫片,它允许在一台机器上存在多个.NET安装.如果您在自己的常规应用程序中嵌入.NET语言,Mscoree.dll是您将使用的库.
Mscoree.dll查看从PE可执行文件加载的元数据,特别是CLR标头和目标.NET运行时版本.从它可以CorBindToRuntimeEx 2到正确的CLR版本.
CorBindToRuntimeEx加载正确的.NET运行时实现(并返回一个指向COM接口的指针,允许您调用该.NET运行时.此代码从%WINDIR%\ Microsoft.NET\Framework\v ####中的dll加载#.
我不确定在这一点上是谁,但是mscoree shim可能使用.NET ICLRRuntimeHost接口指针来调用方法来初始化.NET运行时,垃圾收集器,IL解释器,JIT和IHostControl接口(允许.NET解释器到回到托管过程),最终告诉Interpreter开始执行编译应用程序的IL代码.
(我学到了很多东西 - 这些链接背后有很多信息,我当然没有完全了解所有这些!)
http://msdn.microsoft.com/en-us/library/xh0859k0.aspx
http://msdn.microsoft.com/en-us/magazine/bb985994.aspx
Windows可执行文件是可移植可执行文件,这种格式为Windows提供加载和运行程序所需的信息.当Windows遇到.NET程序时,它会加载CLR的一个实例,并将程序的执行交给新的CLR实例.每个运行的.NET程序都托管在它自己的CLR实例中.
CLR进程加载IL程序并将其编译为本机代码(JIT),然后执行代码,负责该程序的内存管理和垃圾收集.