Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/gwt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 用c语言编译/序列化一段代码#_C#_Reflection_Roslyn - Fatal编程技术网

C# 用c语言编译/序列化一段代码#

C# 用c语言编译/序列化一段代码#,c#,reflection,roslyn,C#,Reflection,Roslyn,我的目标是编写一个可以编译/序列化任何代码段的类。我在想一些想法,这只是一个概念,我不希望你们写出完整的解决方案,我在想最好的方法。 我想到了两个想法: 在编译器类中创建一个接口,然后读取接口方法体并使用roslyn将其编译成单独的程序集 序列化表达式树 公元1年。第一概念 public class Runnable : IRunnable { void Run(); } public interface ICodeRunner { void RunCode<T>(

我的目标是编写一个可以编译/序列化任何代码段的类。我在想一些想法,这只是一个概念,我不希望你们写出完整的解决方案,我在想最好的方法。 我想到了两个想法:

  • 在编译器类中创建一个接口,然后读取接口方法体并使用roslyn将其编译成单独的程序集
  • 序列化表达式树
  • 公元1年。第一概念

    public class Runnable : IRunnable
    {
        void Run();
    }
    
    public interface ICodeRunner
    {
        void RunCode<T>() where T : IRunnable
    }
    
    public class CodeRunner : ICodeRunner
    {
        public void RunCode<T>() where T : IRunnable
        {
            MethodInfo mi = typeof(T).GetMethod("Run");
            MethodBody mb = mi.GetMethodBody();
            // somehow get method body if possible and compile it using roslyn.
            // like this:
            // string syntaxTree = mb.GetMethodBodyToString() // this method doesn't exist. There must be a way to do that
            // CSharpCompilation compilation = CSharpCompilation.Create(
            //    "abc",
            //    new[] { syntaxTree },
            //    new[] { MetadataReference.CreateFromFile(typeof(object).Assembly.Location) },
            //    new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
    
            // using (var dllStream = new FileStream(@"abc.dll", FileMode.OpenOrCreate))
            // using (var pdbStream = new FileStream(@"abc.pdb", FileMode.OpenOrCreate))
            // {
            //    var emitResult = compilation.Emit(dllStream, pdbStream);
            //    if (!emitResult.Success)
            //    {
            //        // emitResult.Diagnostics
            //    }
            // }
        }
    }
    
    公共类可运行:IRunnable
    {
    无效运行();
    }
    公共接口ICodeRunner
    {
    void RunCode(),其中T:IRunnable
    }
    公共类CodeRunner:ICodeRunner
    {
    public void RunCode(),其中T:IRunnable
    {
    MethodInfo mi=typeof(T).GetMethod(“Run”);
    MethodBody mb=mi.GetMethodBody();
    //如果可能的话,以某种方式获取方法体并使用roslyn编译它。
    //像这样:
    //string syntaxTree=mb.GetMethodBodyToString()//此方法不存在。必须有一种方法来实现此目的
    //csharpcomilation=csharpcomilation.Create(
    //“abc”,
    //新[]{syntaxTree},
    //新[]{MetadataReference.CreateFromFile(typeof(object.Assembly.Location)},
    //新的CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
    //使用(var dllStream=newfilestream(@“abc.dll”、FileMode.OpenOrCreate))
    //使用(var pdbStream=newfilestream(@“abc.pdb”、FileMode.OpenOrCreate))
    // {
    //var emitResult=compilation.Emit(dllStream,pdbStream);
    //如果(!emitResult.Success)
    //    {
    ////emitResult.Diagnostics
    //    }
    // }
    }
    }
    
    另一种方法是将lambda作为表达式树序列化到文件中,我看到一些库可以这样做。
    有没有更简单的方法


    我的通用用例是创建一个类,该类可以将一些代码(逻辑)和负载序列化为两个单独的文件,通过网络发送,并在不同的机器上运行一段代码+负载。接口为exe文件和通过导线发送的输入文件。对于这个问题,有现成的解决方案吗?

    这通常不起作用,因为IL中存在无法用C#表示的结构;这正是反编译器面临的问题。对于您的特定用例,您不必担心,如果源代码是C#,但是如果源代码是C#,您已经有了一个完美的序列化格式——它就是源代码。如果只处理在运行时生成的表达式树,因此没有源代码,请参见。一般来说,无论采取何种安全预防措施,通过网络发送任意代码都会让我感到非常不舒服。如果你能为你的有效负载设计一种特定于领域的语言,你会有更多的前期工作,但从长远来看,你会节省维护费用。如果要发送任意代码,根本不必进行反编译——只要按原样传输编译后的可执行文件,或者传输
    ildasm
    的输出(如果必须具有可读文本)。不需要使用C作为中介。因此,您试图重新发明称为COM/COM+的轮子?这通常无法工作,因为IL中存在无法用C表示的构造;这正是反编译器面临的问题。对于您的特定用例,您不必担心,如果源代码是C#,但是如果源代码是C#,您已经有了一个完美的序列化格式——它就是源代码。如果只处理在运行时生成的表达式树,因此没有源代码,请参见。一般来说,无论采取何种安全预防措施,通过网络发送任意代码都会让我感到非常不舒服。如果你能为你的有效负载设计一种特定于领域的语言,你会有更多的前期工作,但从长远来看,你会节省维护费用。如果要发送任意代码,根本不必进行反编译——只要按原样传输编译后的可执行文件,或者传输
    ildasm
    的输出(如果必须具有可读文本)。不需要使用C#作为中介。那么你想重新发明一个叫做COM/COM+的轮子?