有人看过.NET CLI源代码吗?能指导一下关于ClassLoad如何装载一个类的过程吗?

解决方案 »

  1.   

    好像和类的加载过程无关:无论是Remoting方式还是Local方式,类的加载过程和在内存中的形式是完全一样的,不同的是,Local方式new是直接在内存里构件对象,Remoting则是构建一个用于远程调用的Proxy。.NET允许用统一的语法创建Local和Remoting对象(在C#里面是new语句,在MSIL里面是newobj指令),这就意味着,每次创建对象的时候CLR都必须检查正在创建的对象类型是否已经通过RemotingConfiguration注册为Remoting类型了(remoting config文件完成的也是同样的工作)。这样显然会影响效率,所以.NET为每个类型预留一个标志位,当该类型的第一个对象被实例化的时候,CLR检察该类型是否已经注册,并设置相应的标志,此后的对象创建都是根据这个标志进行,不需要在重复检查是否已经进行了Remoting注册。这种做法的一个问题就是,如果你在注册值前已经创建了该类型的一个实例,那么注册之后的new语句仍然会创建本地对象,而不是Remoting对象。由于Activator.GetObject不需要检查已经注册的Remoting类型(参数已经提供了足够的信息用于建立Proxy),所以Activator.GetObject不受这种实现方法的影响。
      

  2.   

    通常不建议在Remoting和Local同时使用同一个类型的对象,这样会引起很多的问题。这种情况下使用interface可能更好一些。BTW: 如果有兴趣察看源代码的化,可以看sscli中的JIT部分:
    sscli\clr\src\vm\jitinterface.cpp line 7874: JIT_NewCrossContext
    这里是JIT编译代码在创建对象时调用,用于区分本地和远程类型的代码。这里你可以看到设置/检查标志的详细信息(CRemotingServices::RequiresManagedActivation)。
      

  3.   

    谢谢您的支持, 我在实际操作中绝对不会这样用的,因为这样做会导致一系列问题。不过我在看Remoting文档的时候,觉得这样的调用方法很新奇,想看一下其原理。如果按照您所述的,是否是说这个调用是在JIT中完成的?我原来一直认为是Class Loader的问题,因此一直跟踪clsLoader.cpp和class.cpp的源代码,但是一直没有结果。文档上说class是在第一次声明的时候装载的(Main程序入口的类除外),class loader的装载次序是:
    1.configuration文件(其实我一直纳闷这个因为我的执行程序就是TestRemoting.exe.config,为什么clr不自动装载我的config文件)
    2.App路径
    3.GAC路径但是实际上我经过了测试,发现一个问题:
     RemotingConfiguration.Configure之后,其实Assembly已经装载到了AppDomain中了,这是否意味着RemotingConfiguration.Configure工作已经完成了装载RemoteServer类的过程了呢?我察看了RemotingConfiguration的源代码,并未发现装载Assembly的过程,您能指导一下吗?
      

  4.   

    >> 1.configuration文件(其实我一直纳闷这个因为我的执行程序就是TestRemoting.exe.config,为什么clr不自动装载我的config文件)Remoting的配置文件不属于x.exe.config的格式范围,所以即使CLR试图加载这个config,也没有办法解释它的内容。>> RemotingConfiguration.Configure之后,其实Assembly已经装载到了AppDomain中了,这是否意味着RemotingConfiguration.Configure工作已经完成了装载RemoteServer类的过程了呢?RemotingConfiguration.Configure并不需要特别的加载Assembly,因为AssemblyLoad是CLR的职责。只要当前的代码引用了类型,在第一次执行的时候CLR就会自动加载,Configure工作过程中显然需要引用类型名称,这样就有可能导致Assembly被加载到内存。
      

  5.   

    能指出一下RemotingConfigure具体流程(原代码)吗?我甚至没有看到如何调度Assembly的,类是如何重写的。
      

  6.   

    Configure函数什么也没做,只是简单的把类型和相关的信息加入一张内部的表中。供以后的newobj或者Activator.GetObject函数使用而已。