C# 动态编译

摘要:
没试过:https://developer.xamarin.com/api/namespace/System.CodeDom/Evaluator:这玩意其实不错,但由于Unity目前只支持到.net3.5,而3.5版的Mono.CSharp的Evaluator又比较烂,不支持类跟函数,只能解析简单的语句小试牛刀C#作为脚本语言执行解密https://forum.unity3d.com/threads/mono-csharp-evaluator.102162/http://answers.unity3d.com/questions/309490/is-it-possible-to-compile-and-run-c-code-on-the-fl.htmlpublicclassData{publicstaticintn=0;publicstaticGameObjectgo=null;}Mono.CSharp.Evaluator.Init;Assemblya=Assembly.GetExecutingAssembly();Mono.CSharp.Evaluator.ReferenceAssembly;Mono.CSharp.Evaluator.Run;Debug.Log;//5支持在PC跟安卓上,IOS不行调用Mono编译器动态编译:CodeDom是比较完美的解决方案,无奈打包后的程序里的mono只包含runtime部分,没有编译部分工具,所以会导致打包后运行失败,所以Github上已经有大佬将mono里的msc部分单纯提取出来,编译成一个dll,供项目调用。

1.C#层:利用.NET framework的CodeDom或Mono的Evaluator动态编译解释CS脚本

2.IL层:利用System.Reflection.Emit或Mono.Cecil动态生成IL指令并执行

3.造轮子自己实现IL解释器(取代.NET或Mono的IL解释器,这种方案可以绕过苹果实现热更新)

4.直接调用Mono的编译器进行编译生成dll,例如Win平台"..Monoingmcs.bat"

参考:

  1. C#动态创建和动态使用程序集、类、方法、字段等

  2. Emit动态生成代码

  3. Unity3d跨平台原理

  4. 动态生成与编译(一)----入门

  5. C#脚本引擎 CS-Script 之(一)——初识

  6. IL解释器:ILRuntimeL#ApolloClr

  7. ClearscriptpaxScript.NET
  8. Compile C# at runtime in Unity3D

  9. Dynamically executing code in .Net(比较不错,他还提供了个wwScripting,方便使用,还支持将代码加载到新的AppDomain)

  10. C#Light/Evil 是一组pure C#写成的脚本语言

CodeDom:

经过最新研究,这玩意其实就是去调用gmcs来生成代码的,跟直接用gmcs没差,在Unity编辑器里可以直接用,但打包出来就不行了,因为认不出gmcs的路径

微软链接:https://msdn.microsoft.com/en-us/library/saf5ce06(v=vs.110).aspx

不生成程序,直接写在内存并调用生成的内容:http://stackoverflow.com/questions/24871955/c-sharp-compilerresults-generateinmemory

1.动态编译CS代码

作者:知乎用户
链接:https://www.zhihu.com/question/31230641/answer/51098145
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingMicrosoft.CSharp;
usingSystem.CodeDom.Compiler;
classProgram
{
    static void Main(string[] args)
    {
        var csc = new CSharpCodeProvider(new Dictionary<string, string>() { { "CompilerVersion", "v3.5"} });
        var parameters = new CompilerParameters(new[] { "mscorlib.dll", "System.Core.dll" }, "foo.exe", true);
        //生成exe,若为false,则生成dll
        parameters.GenerateExecutable = true;
        CompilerResults results =csc.CompileAssemblyFromSource(parameters,
        @"using System.Linq;
            class Program {
              public static void Main(string[] args) {
                var q = from i in Enumerable.Range(1,100)
                          where i % 2 == 0
                          select i;
              }
            }");
        results.Errors.Cast<CompilerError>().ToList().ForEach(error =>Console.WriteLine(error.ErrorText));
    }
}

这种方法方便,强大,但缺点是不支持打包后的版本(不管是PC还是安卓,毕竟在Editor里有集成msc,打包后没有),即使你将Unity的PlayerSetting里的Api Compatibitility Level设置为.NET 2.0也没办法,顶多是加入了namespace的引用,能在代码里调用和编译通过而已,但实际运行起来,还是会报错:

C# 动态编译第1张

官方论坛里有人遇到同样的错误:http://answers.unity3d.com/questions/309490/is-it-possible-to-compile-and-run-c-code-on-the-fl.html

据说Xamarin支持?没试过:https://developer.xamarin.com/api/namespace/System.CodeDom/

Evaluator:

这玩意其实不错,但由于Unity目前只支持到.net 3.5,而3.5版的Mono.CSharp的Evaluator又比较烂,不支持类跟函数,只能解析简单的语句

public classData
{
     public static int n = 0;
     public static GameObject go = null;
}
Mono.CSharp.Evaluator.Init(new string[] {} );
Assembly a =Assembly.GetExecutingAssembly();
Mono.CSharp.Evaluator.ReferenceAssembly(a);
Mono.CSharp.Evaluator.Run("Data.n=Data.n+5;");
Debug.Log(Data.n); //5

支持在PC跟安卓上,IOS不行

调用Mono编译器动态编译:

CodeDom是比较完美的解决方案,无奈打包后的程序里的mono只包含runtime部分,没有编译部分工具,所以会导致打包后运行失败,

所以Github(mcs-ICodeCompiler)上已经有大佬将mono里的msc部分单纯提取出来,编译成一个dll,供项目调用。

原理很简单,CodeDom不是需要msc么?直接将所需的程序集部分提供给它就行,这部分很小,近1M左右,如果是整个mono项目,那非常巨大,估计几十M。

注意:这种方法需要你的Unity项目必须是.NET 2.0,而不是.NET 2.0 Sub,如果是sub也所谓,直接将完整版的.NET 2.0里的System.dll替换进来即可。

注意2:CodeDom目前有个BUG,就是不支持Enum,若使用会使程序崩溃:https://bugzilla.xamarin.com/show_bug.cgi?id=24607

免责声明:文章转载自《C# 动态编译》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇GIS开源程序收集学习笔记:oracle学习一:oracle11g体系结构之服务器结构、数据字典下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

PCRE函数简介和使用示例

PCRE是一个NFA正则引擎,不然不能提供完全与Perl一致的正则语法功能。但它同时也实现了DFA,只是满足数学意义上的正则。 PCRE提供了19个接口函数,为了简单介绍,使用PCRE内带的测试程序(pcretest.c)示例用法。 pcre_compile原型:#include <pcre.h>pcre *pcre_compile(cons...

安装Linux应用软件的五种基本方法

要充分发挥电脑的作用,就得有大量的应用软件,完成不同的工作。在Windows环境中安装各种应用软件的思路与方法,想必大家早已熟悉。然而,在使用Linux时,我们却总会被这些本不应该是问题的问题所困扰:怎么安装应用软件?我的软件安装在什么地方?如何删除不要的应用软件?……   下面,我们就一起来认识一下这些方面的知识。 一、解析Linux应用软件安装包...

vue 服务端渲染 vs 预渲染(1)

服务端渲染: 1、将完整的html输出到客户端 2、要使用通用代码 优点 :  1、首次渲染快(无需等所有的js都完成下载)   2、利于seo 缺点:  1、更多的服务器负载 2、开发受限 3、需要处于node.js/php server 运行环境 预渲染:  1、使用少数营销页的seo   2、生成对特定路由静态的html文件 优点:   1、预渲染更...

liteos 从入门到放弃

这两天收到一份sdk,hisi 3516cv200 liteos的sdk 正好手头有硬件,就随便编译玩玩. 解压sdk. Hi3518E_SDK_V5.0.5.0 ll@ubuntu:~/work2016/liteos/Hi3518E_SDK_V5.0.5.0$ ls -lh total 32K drwxrwxr-x 4 ll ll 4.0K Oct 25...

android layout 按比例布局

为了创建比例大小的子View,可以将LinearLayout的宽度和高度设为fill_parent, 而将子View的宽度或是高度设为0,然后为子View设置不同权重(weight) ,这样子View的大小就会权值成比例。 本例使用横向LinearLayout,LinearLayout的android:layout_width=”match_paren...

Android学习之五:android一些基本控件

每一个GUI开发工具都会提供一些基本的控件,例如Label和Button 等,下面我们来看下Android的一些基本控件。 Label:就是只用来显示些文本信息,而且不需要编辑的控件,在Android中是使用TextView控件的。我们来看一下在xml文件下面怎么定义该控件,我们来看以下的xml代码: <TextView android:lay...