ここで説明されているように、C# プログラム内から C# を生成して実行しています。
ご覧のとおり、コンパイルされたコードの「実行」メソッドを 経由で呼び出すことができますclassType.GetMethod("Execute").Invoke(instance, args)
。
変数は、メソッドargs
に渡されるパラメーターのオブジェクト配列です。Execute
このシステムを使用して、比較的簡単に問題なく通過することができました。
ここで大きな問題が発生します...Execute
メソッドがメイン プログラムにシグナルを送ることができるように、コールバック関数 (デリゲートなど) を渡す必要があります。署名に一致する型指定されたデリゲートを渡そうとしましたが、失敗しました (実行さえしませんでした)。次に、タイプを指定せずにデリゲートを渡そうとしましたが、これも失敗しました (今回は、呼び出しが試行されたときに失敗しました)。また、それを通常のオブジェクトとして渡し、生成されたコード内でキャストして戻そうとしましたが、何も変わりませんでした。
私は C# にあまり興味がないので、非常に基本的なことが欠けていると思います。また、有効なテスト ケース コードはありませんが、上記のリンクを使用するのはそれほど難しくありません..
参照: http://support.microsoft.com/kb/304655
編集:これはサンプルコードです:
class CompilerTest {
private object obj;
private MethodInfo mtd;
public void on_log(string type, string message){
MessageBox.Show(type.ToUpper() + ": " + message);
}
public void compile(){
CodeDomProvider c = CodeDomProvider.CreateProvider("CSharp");
CompilerParameters cp = new CompilerParameters();
cp.ReferencedAssemblies.Add("system.dll");
cp.ReferencedAssemblies.Add("system.data.dll");
cp.ReferencedAssemblies.Add("system.windows.forms.dll");
cp.CompilerOptions = "/t:library";
cp.GenerateInMemory = true;
StringBuilder sb = new StringBuilder("");
sb.AppendLine("using System;");
sb.AppendLine("using System.Data;");
sb.AppendLine("using System.Reflection;");
sb.AppendLine("using System.Windows.Forms;");
sb.AppendLine("public delegate void LoggerInternal(string type, string message);");
sb.AppendLine("public class CSCodeEvalCls{");
sb.AppendLine(" private LoggerInternal log;");
sb.AppendLine(" public void E(object lgr){");
sb.AppendLine(" this.log = (RuleLoggerInternal)lgr;");
sb.AppendLine(" }");
sb.AppendLine(" private void L(string type, string message){");
sb.AppendLine(" this.log(type, message);");
sb.AppendLine(" }");
sb.AppendLine("}");
CompilerResults cr = c.CompileAssemblyFromSource(cp, sb.ToString());
System.Reflection.Assembly a = cr.CompiledAssembly;
this.obj = a.CreateInstance("CSCodeEvalCls");
this.mtd = this.obj.GetType().GetMethod("E");
}
public void execute(){
this.mtd.Invoke(this.obj, new object[]{ this.on_log });
}
}
CompilerTest test = new CompilerTest();
test.compile();
test.execute();