.NET TIPS

プログラムからソース・コードをコンパイルして実行するには?

デジタルアドバンテージ
2003/12/19

 「TIPS:プログラムからソース・コードをコンパイルするには?」では、プログラム中に埋め込んだソース・コードをコンパイルして実行可能ファイルを出力する方法について解説したが、ここでは実行可能ファイルに出力せずに、コンパイル後に直接呼び出して実行してみる。

 次のサンプル・プログラムは、文字列として埋め込んだソース・コードをプログラムの実行時にコンパイルし、さらにそれを実行するために、そのMainメソッドを呼び出す。結果として「Hello C# World!」のメッセージが出力される。

// compileinvoke.cs

using System;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
using System.Reflection;

public class CompileInvoke {
  static string cs = @"
    public class CSHello {
      public static void Main() {
        System.Console.WriteLine(""Hello C# World!"");
      }
    }";

  public static void Main() {
    CSharpCodeProvider cscp = new CSharpCodeProvider();
    ICodeCompiler cc = cscp.CreateCompiler();

    CompilerParameters param = new CompilerParameters();
    param.GenerateInMemory = true;

    CompilerResults cr = cc.CompileAssemblyFromSource(param, cs);
    Assembly asm = cr.CompiledAssembly;

    Type type = asm.GetType("CSHello");

    MethodInfo mi = type.GetMethod("Main");
    mi.Invoke(null, null);  // 出力:Hello C# World!"
  }
}

// コンパイル方法:csc compileinvoke.cs
ソース・コードをコンパイルし実行するC#のサンプル・プログラム(compileinvoke.cs)

 今回のプログラムでは、ICodeCompilerオブジェクトのCompileAssemblyFromSourceメソッド呼び出し時に指定するコンパイルのパラメータで、GenerateInMemoryプロパティをtrueに設定する。これによりコンパイルされたアセンブリはファイルに出力されずにメモリ上にのみ作成されるようになる(実際にはソース・コードもアセンブリもいったん一時的なディレクトリに作成されているようだが)。

CompilerParameters param = new CompilerParameters();
param.GenerateInMemory = true;

 CompileAssemblyFromSourceメソッドの呼び出したときには、その戻り値であるCompilerResultsオブジェクトのCompiledAssemblyプロパティにより、ロード済みのアセンブリへの参照を得ることができる。

CompilerResults cr = cc.CompileAssemblyFromSource(param, cs);
Assembly asm = cr.CompiledAssembly;

 アセンブリへの参照があれば、それに含まれるCSHelloクラスの型情報をTypeクラス(System名前空間)のオブジェクトとして取得でき、さらにTypeクラスのGetMethodメソッドにより、Mainメソッドの情報をMethodInfoクラス(System.Reflection名前空間)のオブジェクトとして取得できる。

 このようにしてMainメソッドについてのMethodInfoオブジェクトが取得できれば、そのメソッドをInvokeメソッドにより実際に呼び出すことができる。

Type type = asm.GetType("CSHello");

MethodInfo mi = type.GetMethod("Main");
mi.Invoke(null, null);

 このような型やメソッドへのアクセスは、.NET Frameworkの機能の1つである「リフレクション」と呼ばれるものだ。

 なお、ここで呼び出しているMainメソッドはstaticなメソッドであるため、型のインスタンス化は行っていない。End of Article

カテゴリ:クラス・ライブラリ 処理対象:コンパイラ
カテゴリ:クラス・ライブラリ 処理対象:リフレクション
使用ライブラリ:CSharpCodeProviderクラス(Microsoft.CSharp名前空間)
使用ライブラリ:
ICodeCompilerインターフェイス(System.CodeDom.Compiler名前空間)
使用ライブラリ:
CompilerParametersクラス(System.CodeDom.Compiler名前空間)
使用ライブラリ:
CompilerResultsクラス(System.CodeDom.Compiler名前空間)
使用ライブラリ:Typeクラス(System名前空間)
使用ライブラリ:Assemblyクラス(System.Reflection名前空間)
使用ライブラリ:
MethodInfoクラス(System.Reflection名前空間)
関連TIPS:プログラムからソース・コードをコンパイルするには?
 
この記事と関連性の高い別の.NET TIPS
プログラムからソース・コードをコンパイルするには?
文字列で指定したメソッドを呼び出すには?
C#のソース・コードを実行するには?
メソッドやプロパティの有無を確認して呼び出すには?
文字列で指定したクラスのインスタンスを作成するには?
このリストは、(株)デジタルアドバンテージが開発した
自動関連記事探索システム Jigsaw(ジグソー) により自動抽出したものです。
generated by

「.NET TIPS」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)
- PR -

注目のテーマ

Insider.NET 記事ランキング

本日 月間
ソリューションFLASH