启动.net应用程序时会发生什么?

San*_*box 29 .net c# clr

我一直在使用.net开发应用程序已有一段时间了.但是,我仍然不确定CLR是如何知道.net应用程序已经启动的.是否每个应用程序都有一个CLR实例?我不认为这可能是这种情况,因为只有一个GC管理所有.net应用程序的所有内存.CLR是否在后台运行?我很困惑.

mem*_*ech 43

嗯,让我来看看这个.

  1. 有人用C#或.NET"中间语言"或其他托管语言构建.NET应用程序.

  2. 该语言的编译器csc.exe(C#)或ilasm.exe(字节码汇编程序)或其中任何一个生成PE可执行文件.PE可执行文件具有编译器或汇编程序填充的特定结构.那包括:

    • 一个切入点,和
    • 它使用的动态库列表(IMPORT表).其中一个库是mscoree.dll
    • 大量元数据,包括目标.NET运行时版本
  3. 单击可执行文件,从命令行运行或从Win32 API执行时,Windows加载程序实现(在NTDLL.dll中)接管

  4. 加载程序代码负责将可执行文件存入内存,根据需要加载动态链接库,将链接库映射到可执行代码可以访问它们的位置,以及使用映射库的实际地址更新导入地址表.

  5. 一旦准备就绪,加载器就会跳转到入口点(通过我假设的一些恶作剧从内核空间切换到用户空间,或者转换到保护模式,因为应用程序在它自己的受保护的32位或64位内存空间中运行).入口点是mscoree.dll - .NET公共对象运行时执行引擎,它刚刚映射到进程内存中.我已经看到这个DLL被称为.NET启动垫片,它允许在一台机器上存在多个.NET安装.如果您在自己的常规应用程序中嵌入.NET语言,Mscoree.dll是您将使用的库.

  6. Mscoree.dll查看从PE可执行文件加载的元数据,特别是CLR标头和目标.NET运行时版本.从它可以CorBindToRuntimeEx 2到正确的CLR版本.

  7. CorBindToRuntimeEx加载正确的.NET运行时实现(并返回一个指向COM接口的指针,允许您调用该.NET运行时.此代码从%WINDIR%\ Microsoft.NET\Framework\v ####中的dll加载#.

  8. 我不确定在这一点上是谁,但是mscoree shim可能使用.NET ICLRRuntimeHost接口指针来调用方法来初始化.NET运行时,垃圾收集器,IL解释器,JIT和IHostControl接口(允许.NET解释器到回到托管过程),最终告诉Interpreter开始执行编译应用程序的IL代码.

(我学到了很多东西 - 这些链接背后有很多信息,我当然没有完全了解所有这些!)

http://msdn.microsoft.com/en-us/library/xh0859k0.aspx

http://my.safaribooksonline.com/book/programming/microsoft-dotnet/0735619883/a-tour-of-the-clr-hosting-api/ch02lev1sec3

http://msdn.microsoft.com/en-us/magazine/bb985994.aspx

  • 为什么这个答案没有被接受? (2认同)
  • 很好的答案!这应该被接受! (2认同)

blo*_*art 5

Windows可执行文件是可移植可执行文件,这种格式为Windows提供加载和运行程序所需的信息.当Windows遇到.NET程序时,它会加载CLR的一个实例,并将程序的执行交给新的CLR实例.每个运行的.NET程序都托管在它自己的CLR实例中.

CLR进程加载IL程序并将其编译为本机代码(JIT),然后执行代码,负责该程序的内存管理和垃圾收集.

  • 这使得看起来Windows知道应用程序是.NET而Windows应该加载clr.事实并非如此.exe基本上包含一个本机引导程序,它加载.NET clr并启动托管进程.就Windows本身而言,它只是推出了一个本机应用程序,该应用程序加载了一些dll. (10认同)