Cでの動的コードコンパイル#

C#コードからコンパイラを使用するのは非常に簡単です。 しかし、なぜ-これは別の質問です:)。



ハローワールド



最初の簡単な例を書いてみましょう。 コンソールアプリケーションを作成し、次のコードを記述します。

using System;<br> using System.CodeDom.Compiler;<br> using System.Collections. Generic ;<br> using Microsoft.CSharp;<br><br> namespace ConsoleCompiler<br>{<br> internal class Program<br> {<br> private static void Main( string [] args)<br> {<br> // Source code <br> string source =<br> @"<br>namespace Foo<br>{<br> public class Bar<br> {<br> static void Main(string[] args)<br> {<br> Bar.SayHello();<br> }<br><br> public static void SayHello()<br> {<br> System.Console.WriteLine(" "Hello World" ");<br> }<br> }<br>}<br> " ;<br><br> // <br> Dictionary< string , string > providerOptions = new Dictionary< string , string ><br> {<br> { "CompilerVersion" , "v3.5" }<br> };<br> CSharpCodeProvider provider = new CSharpCodeProvider(providerOptions);<br><br> CompilerParameters compilerParams = new CompilerParameters<br> {OutputAssembly = "D:\\Foo.EXE" , GenerateExecutable = true };<br><br> // <br> CompilerResults results = provider.CompileAssemblyFromSource(compilerParams, source);<br><br> // <br> Console .WriteLine( "Number of Errors: {0}" , results.Errors.Count);<br> foreach (CompilerError err in results.Errors)<br> {<br> Console .WriteLine( "ERROR {0}" , err.ErrorText);<br> }<br> }<br> }<br>} <br><br> * This source code was highlighted with Source Code Highlighter .





実行して確認:

First Sample

最初に注意する必要があるのは、2つの名前空間(名前空間)の使用です。 これらのクラスには、コンパイルの鍵が含まれています。 この例では、.NET Framework 3.5でコンパイルすることと、このアプリケーションを実行する機能を備えた出力-Foo.exeで取得するものを示します。



例はより複雑で、Linqを使用します



次に、例を複雑にし、コンパイルされたコードにLinqを追加します。

string source = @"<br> using System.Collections.Generic;<br>using System.Linq; <br><br>namespace Foo<br>{<br> public class Bar<br> {<br> static void Main(string[] args)<br> {<br> Bar.SayHello();<br> }<br><br> public static void SayHello()<br> {<br> System.Console.WriteLine(" "Hello World" ");<br> System.Console.WriteLine( string.Join(" "," ", Enumerable.Range(0,10).Select(n=>n.ToString()).ToArray() ) ); <br> }<br> }<br>}" ; <br><br> * This source code was highlighted with Source Code Highlighter .





追加された行は赤でマークされています。変更されたコンパイル済みコードで前の例を実行しようとすると、コンパイルエラーが表示されます。

Compiler Error

コンパイルを成功させるには、コンパイルオプションでSystem.Core.dllアセンブリへの参照を追加する必要があります

compilerParams.ReferencedAssemblies.Add( "System.Core.Dll" ); <br><br> * This source code was highlighted with Source Code Highlighter .





そして今、すべてが動作します:

Linq Sample

作成したアセンブリをコードで使用します



ここで、実行可能ファイルの代わりにアセンブリFoo.dllをコンパイルし、コンパイル直後に、コンパイルされたメソッドをロードして使用してみましょう。 コンパイルされたコードを変更し、より簡単にします。

stringsource = @"<br>using System.Collections.Generic;<br>using System.Linq;<br><br>namespace Foo<br>{<br> public class Bar<br> {<br> public static void SayHello()<br> {<br> System.Console.WriteLine(" "Hello World" ");<br> System.Console.WriteLine( string.Join(" "," ", Enumerable.Range(0,10).Select(n=>n.ToString()).ToArray() ) );<br> }<br> }<br>}" ; <br><br> * This source code was highlighted with Source Code Highlighter .





コンパイラの設定を変更します。次に、dllファイルを収集します。

const string outputAssembly = "D:\\Foo.dll" ;<br>CompilerParameters compilerParams = new CompilerParameters {OutputAssembly = outputAssembly, GenerateExecutable = false }; <br><br> * This source code was highlighted with Source Code Highlighter .





Reflectionを使用してコンパイルとエラーチェックを行った後(System.Reflectionを使用して名前空間に接続することを忘れないでください)、コンパイルされたdllのFoo.Bar.SayHello()メソッドを呼び出します。

Console .WriteLine( "Try Assembly:" );<br> Assembly assembly = Assembly .LoadFile(outputAssembly);<br>Type type = assembly.GetType( "Foo.Bar" );<br>MethodInfo method = type.GetMethod( "SayHello" );<br>method.Invoke( null , null ); <br><br> * This source code was highlighted with Source Code Highlighter .





結果:

Final Result

最後の例はmydrive.live.comからダウンロードできます。

ここから、動的コンパイルと基本的な例に関する情報を取得しました。SaveenReddyのブログ-C#コードの動的コンパイルのウォークスルー (英語)。

プログイット



All Articles