CodeDOM浅析(下)

CodeDOM浅析(下)

 

生成以后是编译了。在生成的时候,从GenerateCodeFromCompileUnit()这个方法开始,ICodeGenerator里面的其他几个方法都可以被调用到;而在ICodeCompiler里,接口里的方法最后都会调用到这么一个FromFileBatch()方法里来。那么看看在CodeCompiler这个类里是如何实现这个方法的:

 

protected   virtual  CompilerResults FromFileBatch(CompilerParameters options,  string [] fileNames) {
      …….
//前面一些处理略
      string text3 = this.CmdArgsFromParameters(options) + " " + CodeCompiler.JoinStringArray(fileNames, " ");
      
string text4 = this.GetResponseFileCmdArgs(options, text3);
      
string text5 = null;
      
if (text4 != null)      {
            text5 
= text3;
            text3 
= text4;
      }

      
this.Compile(options, Executor.GetRuntimeInstallDirectory(), this.CompilerName, text3, ref text1, ref num1, text5);
      ……
//下面为编译结果的处理,略
}

 

问题在this.Compile()这里了,再寻根问底下去:

 

internal   void  Compile(CompilerParameters options,  string  compilerDirectory,  string  compilerExe,  string  arguments,  ref   string  outputFile,  ref   int  nativeReturnValue,  string  trueArgs) {
     ……
      
string text2 = compilerDirectory + compilerExe;
     ……
      nativeReturnValue 
= Executor.ExecWaitWithCapture(options.UserToken, "/"" + text2 + "/" " + arguments, options.TempFiles, ref outputFile, ref text1, text3);
     ……
}

 

出来一个新东西Executor,执行者?就是这个东西,调用命令行编译就是它来做的,而CodeCompiler只是提供出一个命令行字符串而已。ExecutorSystem.CodeDom.Compiler里公开的sealed类,里面全是一些静态方法,追呀追呀追,最后到了这里:

 

private   static   int  ExecWaitWithCaptureUnimpersonated(IntPtr userToken,  string  cmd,  string  currentDir, TempFileCollection tempFiles,  ref   string  outputName,  ref   string  errorName,  string  trueCmdLine) {
       …….
       flag1 
= UnsafeNativeMethods.CreateProcess(nullnew StringBuilder(cmd), nullnulltrue0new HandleRef(null, ptr4), currentDir, startupinfo1, process_information1);
       …….
       
int num2 = SafeNativeMethods.WaitForSingleObject(new HandleRef(null, process_information1.hProcess), 600000);
       …….
       
if (!UnsafeNativeMethods.GetExitCodeProcess(new HandleRef(null, process_information1.hProcess), ref num3))       {
          ……        
         }

        
return num3;
      …….
 }

 

好熟悉的东西呀,什么CreateProcessWaitForSingleObject。跑到SafeNativeMethods(UnsafeNativeMethods)那边一瞧,不得了,熟悉的面孔一大堆,好多的[DllImport()]。原来在.NET下调用命令行没什么新着呀。

 

上面的东西跟好象跟Provider一点关系都没有。不过也不对呀,编译的时候它是如何找到编译器的呢?Provider肯定在这里起作用的喽。就是this.Compile()那个方法的第三个参数:this.CompilerName,这是一个抽象的属性,具体的值在相关的Provider里提供。注意一下CSharpCodeGenerator这个类,它是从CodeCompiler继承的。这里有个比较有趣的继承关系:

public abstract class CodeGenerator : ICodeGenerator
public abstract class CodeCompiler : CodeGenerator, ICodeCompiler
internal class CSharpCodeGenerator : CodeCompiler

倒不是继承关系有趣,而是名字取得比较的趣,CSharpCodeGenerator这个类原来把生成与编译功能的都包括在里面了,上面那个CompilerName的属性值就是在CSharpCodeGenerator里提供的,好象有点乱(看来看去总觉得当初CodeCompilerCodeGenerator继承是为了后面CSharpCodeGenerator准备的﹐在CodeCompiler里根本是没改写过CodeGenerator什幺东西﹐一股脑就丢给CSharpCodeGenerator)。刚开始没注意到这个继承关系,而且也没注意到CSharpCodeGenerator里有CompilerName这样的属性值(藏得太下面了,要点两下滚动条才出来),对它的值是如何得到的百思不得其解。

    编译的事也搞定。

 

System.CodeDom.Compiler里三大接口去其二,还有一个ICodeParser没人管,MS自己也没有提供相应的实现的,在网上倒是有看到过一个。很吓人的东西,复杂的字符串分析,整段整段的switch。描了两眼,还是没有跳进去。

 

CodeDOM分析就此结束,看下来一点奥秘都没有,否则也不叫浅析了。其实奥秘都在省略的那些东西里,那些才是见真功夫的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值