2011-02-08 9 views
3

私は最初にこのすべての適切な用語がわからないので、これが既に解決されている場合は謝罪し、あらかじめ定義された関数への新しく構築されたC#アセンブリのアクセス

私はプログラムでコンパイルしたC#コードをスクリプト言語として機能させるためにC#でプログラムを作成しようとしています。ここで

はその負荷プログラムのための私のコード例で、コードをコンパイル:

using Microsoft.CSharp; 
using System; 
using System.CodeDom.Compiler; 
using System.Collections.Generic; 
using System.IO; 
using System.Reflection; 

namespace RuntimeCompilation 
{ 
    public class Program 
    { 
     public static void Main(string[] args) 
     { 
      Program b = new Program(); 
      CompilerResults results = b.BuildAssembly("Class1.cs"); // compiles the class 

      if (results.Errors.Count > 0) 
      { 
       System.Console.Out.WriteLine("Errors Follow:"); 
       String ErrorText = ""; 
       foreach (CompilerError CompErr in results.Errors) 
       { 
        ErrorText = ErrorText + 
         "Line number " + CompErr.Line + 
         ", Error Number: " + CompErr.ErrorNumber + 
         ", '" + CompErr.ErrorText + ";" + 
         Environment.NewLine + Environment.NewLine; 
       } 
       System.Console.Out.WriteLine(ErrorText); 
      } 
      else 
      { 
       Assembly assembly = results.CompiledAssembly; 
       foreach (Type type in assembly.GetTypes()) 
       { 
        System.Console.WriteLine("Type found: " + type.FullName); 
        System.Console.WriteLine("Creating Instance:"); 
        System.Console.WriteLine("======================="); 
        assembly.CreateInstance(type.FullName); 
        System.Console.Out.WriteLine("======================="); 
        System.Console.Out.WriteLine("Done"); 
       } 
      } 
      System.Console.Out.WriteLine("DONE."); 
     } 

     // Compile a file of source and return the CompilerResults object. 
     private CompilerResults BuildAssembly(string filename) 
     { 
      TextReader tr = new StreamReader(filename); 
      string code = tr.ReadToEnd(); 
      CSharpCodeProvider provider = new CSharpCodeProvider(); 
      CompilerParameters compilerparams = new CompilerParameters(); 
      compilerparams.GenerateExecutable = false; 
      compilerparams.GenerateInMemory = true; 
      return provider.CompileAssemblyFromSource(compilerparams, code); 
     } 

     public bool iCanHasAccess() 
     { 
      return true; 
     } 
    } 
} 

そして、ここではそれを構築するクラスは、次のとおりです。

using System; 
using RuntimeCompilation; 

namespace RuntimeCompilation 
{ 
    public class Class1 
    { 
     public Class1() 
     { 
      System.Console.WriteLine("This was instancialized"); 
      if (Program.iCanHasAccess()) 
       System.Console.WriteLine("I have access"); 
     } 
    } 
} 

プログラムによって出力される誤差があることですname現在のコンテキストにプログラムが存在しません。 「スクリプト」プログラムがコンパイルプログラムの機能やメンバーにアクセスできるようにするにはどうすればよいですか?

私は、ユーザーが再構築を必要とせずにプログラム内のコンポーネントの動作を変更できるように、実行時のオーバーヘッドを最小限に抑えながら簡単な方法を可能にしようとしています。これがC#アセンブリでは不可能な場合は、おそらくLUAを使用しますが、避けたいのですが。この製品がXBox360で動作するようにしたいので、XNAを使用して展開する前に、全プロジェクトとスクリプトを一緒にコンパイルする必要があります。

+0

'Mono.CSharp.Evaluator'をチェックしてください - それはコンパイラサービスを持っているので、それを使ってソースコード文字列を評価することができます。 –

+0

Microsoft.CSharp.CSharpCodeProviderも同様に、提供されたソースに例示されているように、Mono環境はXNAからXBox360への展開をサポートしていません。 – acp10bda

答えて

4

あなたが好きなもの、すなわち、現在のアセンブリへの参照が必要になります:

compilerparams.ReferencedAssemblies.Add("my.dll"); // or .exe 

しかし - 以下は、まだ失敗します。

 if (Program.iCanHasAccess()) 
      System.Console.WriteLine("I have access"); 

iCanHasAccess()インスタンスであるため、メソッドではなく、staticメソッドです。

+0

ええ、私はそれが公共の静的であることを意味したことに気づいた。では、私のプログラムを参考にどのように追加しますか? – acp10bda

+0

愚かな編集期限...つまり、「プログラム」が利用可能であることを確認するために、「my.dll」の代わりになるものは何ですか?それは可能ですか、スクリプトで使用可能な関数をホストする別のアセンブリを作成する必要があります...そして、どのように私はまだスクリプト内のオブジェクトの状態をプログラム内で変更できますか? – acp10bda

+0

私は何をすべきか分かりませんでした。この助けを大変ありがとうございます。 – acp10bda

関連する問題