zoukankan      html  css  js  c++  java
  • .在.NET中使用DLR

    转[http://chen1996.blog.163.com/blog/static/4441005220091117102310427/]

    前言

        看到许多朋友写过,在C#中调用DLR脚本的方法,但没有一个说的完整。如今我要说一个详细完整的,希望能对您有所帮助。本文,主要通过C#与IronPython脚本,来体现.NET与脚本互操作的过程。

    什么是DLR

        DLR(Dynamic Language Runtime),是微软主导的一个开源项目。为.NET应用程序,提供了脚本技持。目前版本为0.9,你可以从Codeplex获得源吗。具体可以看我的博文《研究研究DLR》

    总览

     

        应用程序执行脚本的方法有很多种:

    1. 通过ScriptRuntime.ExcuteFile获得ScriptScope
    2. 通过ScriptRuntime.UseFile获得ScriptScope
    3. 通过ScriptRuntime.CreateScope获得ScriptScope,再执行ScripeScope.Execute或ScripeScope.IncludeFile
    4. 通过ScriptRuntime.GetEngine或ScriptRuntime.GetEngineByFileName获得ScriptEngine。调用ScriptEngine的CreateScriptSourceFromString或CreateScriptSourceFromFile或CreateScriptSourceFromStream创建ScriptSource,再执行ScriptSource.Execute。
    5. 有了ScriptSource也不一定要Execute,可以先调用Compile,产生CompiledCode,最后调用CompiledCode.Execute。

    引用DLR

        首先,当然要获得DLR模块对应的DLL。您可以从Codeplex,下载取得。内容如下: 
     
    我在工程目录下面建了一个DLR目录,并把这些文件都Copy进去。然后在解决方案资源管理器视图中,右键“引用”选择“添加引用” 

    点击“浏览”如下图 
     
    将“Microsoft.Scripting.Core.dll”“Microsoft.Scripting.dll”“Microsoft.Scripting.ExtensionAttribute.dll”等文件加入引用。我也不想说的更细了,具体参见Visual Studio的帮助文档。

        被引用的文件编译时会自己Copy到Bin目录去的,但没引用的文件是不会Copy的。我的做法是将这些文件加入工程,然后设置Copy。由于我只要使用Python语言,所以我只Copy了“IronPython.dll”、“IronPython.Modules.dll”与“App.Config”几个文件。

    初始化

        引用了DLR之后,就要对DLR进行初始化。

    1. 首先要使用namespace
      using Microsoft.Scripting.Hosting;
    2. 接着定义与创建ScriptRuntime
      ScriptRuntime env = ScriptRuntime.CreateFromConfiguration();
      ScriptScope scope;
    3. 加载脚本,我在窗体的构造函数里,加入如下标黄的代码

    public Window1()
    {
        InitializeComponent();
    Assembly assembly = Assembly.GetAssembly(typeof(Contact));
        env.LoadAssembly(assembly);
        scope = env.ExecuteFile("Test.py");
    }

        前两行代码,执行ScriptRuntime.LoadAssembly,使脚本能直接使用当前程序集中的Class。接下来执行ScriptRuntime.ExecuteFile,运行Test.py脚本。

    调用脚本的函数

        要调用脚本的函数,首先要定义一个方法的委托。通过委托调用脚本,是最高效的方式。当然,也可以用DynamicObject的TryInvoke方法,调用脚本的函数。这里我介绍委托的方式。

    1. 定义委托
      delegate void ScriptOnLoad(Window window);
      委托的参数形式,与脚本的参数一致。
    2. 调用脚本的函数
      ScriptOnLoad fun;
      if (scope.TryGetVariable<ScriptOnLoad>("OnLoad", out fun))
          fun(this);
      以上代码,TryGetVariable根椐函数名,获得委托。然后,再通过委托就可以直接调用脚本了。当然,您也可以将委托存起来,从而高效的调用函数。

    脚本调用C#

    下面看看Test.py脚本。

    import WpfApplication
    def OnLoad(Window):
        dataProvider = Window.FindResource("myDateCollectionDataSource")
        data = dataProvider.Data;
        c = WpfApplication.Contact("Chen1996", "Chen1996是个聪明人")
        data.Add(c)

        这个脚本不长,但有三个关键点值得关注。

        第一行的import语句,相当于C#的using。其中WpfApplication,是这个C#程序的名字空间。之前初始化时调用LoadAssembly,还记得吗?ScriptRuntime的这个函数,就是用来加载程序集供脚本使用的。

        接下来第三行,Window.FindResource,非常简单的调用C#中的方法。DLR提供得,.NET原生支持就是好。后面第四行与第六行也都一样。这里并不依赖,初始化时通过LoadAssembly加载的程序集,因为一切都源参数Window这个对像。

        第四行,创建了一个WpfApplication.Contact的对象。WpfApplication,就是之前初始化时加载的程序集。为了要使用这个程序集里的类,就必须先加载。然后,就可以像使用脚本自己的类型一样使用了。还是得益于DLR,为我们提供的.NET原生支持,哈哈。

    总之,C#与Python之间互操作,非常的简单又高效。同理通过这个例子,完全可以应用到所有的脚本语言及.NET语言。

  • 相关阅读:
    计算fibonacci数(多种方法)
    数组求和(两种方法)
    C语言二级指针(指向指针的指针)
    唯品会海量实时OLAP分析技术升级之路
    hive 调优(一)coding调优
    supsplk 服务器被植入木马 挖矿 cpu使用 700%
    OPTS参数设置
    Yarn 内存分配管理机制及相关参数配置
    hive on tez 任务失败
    hive 调优(三)tez优化
  • 原文地址:https://www.cnblogs.com/frankzye/p/2031997.html
Copyright © 2011-2022 走看看