22

exeやその他の種類のファイルを生成せずに、基本的にメモリからファイルを実行することなく、保存されたコードをコンパイルして実行できるかどうか疑問に思っていました。

基本的に、メイン アプリケーションにはいくつかの保存されたコード (潜在的に変更されるコード) があり、コードをコンパイルして実行する必要があります。ファイルを作成せずに。

ファイルを作成し、プログラムを実行してから、ファイルを削除することはできません。コンパイルされたコードはメモリから実行する必要があります。

コード例、ポインタ、またはほとんど何でも歓迎します:)

4

8 に答える 8

36
using (Microsoft.CSharp.CSharpCodeProvider foo = 
           new Microsoft.CSharp.CSharpCodeProvider())
{
    var res = foo.CompileAssemblyFromSource(
        new System.CodeDom.Compiler.CompilerParameters() 
        {  
            GenerateInMemory = true 
        }, 
        "public class FooClass { public string Execute() { return \"output!\";}}"
    );

    var type = res.CompiledAssembly.GetType("FooClass");

    var obj = Activator.CreateInstance(type);

    var output = type.GetMethod("Execute").Invoke(obj, new object[] { });
}

これにより、含まれているソースコード文字列から単純なクラスがコンパイルされ、クラスがインスタンス化されて、そのクラスで関数が反射的に呼び出されます。

于 2010-07-06T18:08:56.957 に答える
5

System.Linq.Expressionsティムの回答に追加する方法の例を次に示します。明らかに、これは最も美しいコードではありませんが、この素敵なツリーのような形式にすることで、開発が非常に簡単になります。

private  Expression<IsWordChar> CreateIsWordCharExpression()
{
    var e = Expression.Parameter(typeof(int), "e");
    var c = Expression.Variable(typeof(char), "c");
    var returnLabel = Expression.Label(Expression.Label(typeof(bool)), _falseConstant);
    var lambda = Expression.Lambda<IsWordChar>(
        Expression.Block(
            new[] { c },
            Expression.IfThen(
                Expression.OrElse(
                    Expression.Equal(e, Expression.Constant(-1)),
                    Expression.Equal(e, _inputLengthVar)
                ),
                Expression.Return(returnLabel.Target, _falseConstant)
            ),
            Expression.Assign(c, Expression.MakeIndex(_str, _stringCharsPropertyInfo, new[] { e })),
            Expression.IfThenElse(
                Expression.OrElse(
                    Expression.OrElse(
                        Expression.OrElse(
                            Expression.AndAlso(
                                Expression.GreaterThanOrEqual(c, Expression.Constant('a')),
                                Expression.LessThanOrEqual(c, Expression.Constant('z'))
                            ),
                            Expression.AndAlso(
                                Expression.GreaterThanOrEqual(c, Expression.Constant('A')),
                                Expression.LessThanOrEqual(c, Expression.Constant('Z'))
                            )
                        ),
                        Expression.AndAlso(
                            Expression.GreaterThanOrEqual(c, Expression.Constant('0')),
                            Expression.LessThanOrEqual(c, Expression.Constant('1'))
                        )
                    ),
                    Expression.Equal(c, Expression.Constant('_'))
                ),
                Expression.Return(returnLabel.Target, _trueConstant),
                Expression.Return(returnLabel.Target, _falseConstant)
            ),
            returnLabel
        ),
        "IsWordChar",
        new[] { e }
    );
    return lambda;
}
于 2010-07-06T18:21:08.477 に答える
4

それが可能だ。書きたいコードの量と種類に応じて、簡単か難しいかが決まります。

  • 1 行の式をコンパイルする: System.Linq.Expressions(簡単ですが制限があります)
  • プログラム全体をコンパイルします: System.Reflection.Emit(デバッグは困難ですが、不可能ではありません)

編集: .NET 4.0 より前でSystem.Linq.Expressionsは、C# の 1 行に収まるものに制限されていることに注意してください。つまり、if、while、変数の代入などはありません。

于 2010-07-06T18:00:09.767 に答える
2

はい、できます。非常に遅いですが、確実に実行できます。CodeDOM または(new CSharpCodeProvider().CreateCompiler()).Net を見てください。

于 2010-07-06T17:59:10.763 に答える
1

を調べSystem.CodeDomます。それはまさにあなたが探していることをします。

于 2010-07-06T17:59:35.353 に答える
-1

Python、Ruby、Luaなどのスクリプト言語の埋め込みも見てください。これらはすべて、ディスクに何も書き込まれずにメモリからコードを実行することをサポートしています。

于 2010-07-06T18:11:22.893 に答える