python clr out_[集成IronPython] 添加CLR对象到运行环境

动态类型语言(以下简称:"动态语言"),在10年前就已流行起来。JavaScript更是成为了WEB前台开发的事实标准。但它们进入普通开发 人员的视野也就在近几年。随着Web2.0和敏捷开发方法论的兴起,动态语言的灵活高效的特性成为了它被更多项目选择和使用的理由。一些大型网站已开始使 用动态语言来实现,其中,国内比较优秀的作品有“豆瓣”。微软更是不甘落后,建立了DLR(动态语言运行时)来吸引动态语言爱好者在其上实现动态语言。IronPython就是其主要成员之一。

在本系列文章中,我们将逐步实现一个自定义控件,实现类似IDE的Immediate窗口的功能。用户可以在其中输入和运行IronPython代码。 【返回目录】

在上一节中,我们建立了IronPython运行环境,并且在其中成功的运行了“print "hello world"”的命令。正如上一节的讨论中所看到的,大家都很关心如何让IronPython脚本和我们的运行环境交互。在这一节中,我们将会在DLConsole上添加两个方法,实现将运行环境中的Clr对象传递给IronPython脚本使用。

大家可以从这里下载可运行的源代码。

1. 先看运行效果。

我在DLConsole中输入如下脚本:

1

731655954c7be9d8835ece551b5385f8.pngimportclr2731655954c7be9d8835ece551b5385f8.pngclr.AddReference("System.Drawing")3731655954c7be9d8835ece551b5385f8.pngclr.AddReference("System.Windows.Forms")4731655954c7be9d8835ece551b5385f8.png5731655954c7be9d8835ece551b5385f8.pngfromSystem.DrawingimportColor6731655954c7be9d8835ece551b5385f8.pngfromSystem.Windows.FormsimportFlatStyle7731655954c7be9d8835ece551b5385f8.png8731655954c7be9d8835ece551b5385f8.pngButton1.BackColor=Color.Red;9731655954c7be9d8835ece551b5385f8.pngButton1.FlatStyle=FlatStyle.Flat10731655954c7be9d8835ece551b5385f8.pngButton1.Text="Hello IronPython"

运行结果,如图:

8d5edc08f16106c5818dfc2290d1d291.png

2. 确保脚本可以访问CLR对象

首先,我们需要脚本能够成功的访问CLR对象。我在DLConsole上暴露了两个方法。分别是:

1

731655954c7be9d8835ece551b5385f8.pngpublicpartialclassDLConsole : UserControl224a924a57ba6b3f2b51fc9edb7ea4186.png

9310e85a14af99de4811ff4c77f1f911.png222530190136c9c4cfd237cc0d5cff99.png{31408c5260b2f05e450dee929db9be5f7.pngpublicvoidRegistor(objectobj,stringname)4715f2d05503b99d41f3b6ba2cdccc84d.png

e083dfde5a91f50979fe8979b4012b9d.png222530190136c9c4cfd237cc0d5cff99.png{51408c5260b2f05e450dee929db9be5f7.pngthis._scope.SetVariable(name, obj);65bcb1807ee3e00d2b3c225f0b3f5c751.png    }71408c5260b2f05e450dee929db9be5f7.pngpublicvoidUnRegister(stringname)8715f2d05503b99d41f3b6ba2cdccc84d.png

e083dfde5a91f50979fe8979b4012b9d.png222530190136c9c4cfd237cc0d5cff99.png{91408c5260b2f05e450dee929db9be5f7.pngthis._scope.RemoveVariable(name);105bcb1807ee3e00d2b3c225f0b3f5c751.png    }11f466905a3bcb5dcef110eab799825254.png}

在上一讲的源代码中,我们保存了一个ScriptScope对象。用户输入的脚本就是在这个Scope对象上运行的。因此,我们在这里向ScriptScope中添加的变量,就能够被用户输入的脚本所访问了。

在测试程序中,我添加了如下的代码来将对象注册到脚本运行环境中。

1

731655954c7be9d8835ece551b5385f8.pngpublicpartialclassForm1 : Form224a924a57ba6b3f2b51fc9edb7ea4186.png

9310e85a14af99de4811ff4c77f1f911.png222530190136c9c4cfd237cc0d5cff99.png{31408c5260b2f05e450dee929db9be5f7.pngpublicForm1()4715f2d05503b99d41f3b6ba2cdccc84d.png

e083dfde5a91f50979fe8979b4012b9d.png222530190136c9c4cfd237cc0d5cff99.png{51408c5260b2f05e450dee929db9be5f7.png        InitializeComponent();61408c5260b2f05e450dee929db9be5f7.png71408c5260b2f05e450dee929db9be5f7.pngthis._dlConsole.Registor(this.button1,"Button1");81408c5260b2f05e450dee929db9be5f7.pngthis._dlConsole.Registor(this.textBox1,"TextBox1");95bcb1807ee3e00d2b3c225f0b3f5c751.png    }10f466905a3bcb5dcef110eab799825254.png}

这时,我们就可以实现类似“Button1.Text = "Hello IronPython"”和“Button1.BackColor = TextBox1.ForeColor”这样的脚本了。但是,你会发现,如果你输入类似“Button1.BackColor = Color.Red”的脚本,会产生一个“name 'Color' is not defined”的异常。是因为在目前的Scope中无法找到Color的定义引起的。

3. 使用CLR类型

如果需要在IronPython中使用CLR类型,需要完成以下几个步骤:

a) 引入clr对象:这个对象实现了对CLR访问的一些必要的操作。例如:添加引用。

b) 添加引用:通过clr.AddReference方法,你可以使用Assembly的名字作为参数来添加对这个Assembly的引用。IronPython会使用.NET加载Assembly的策略去寻找和加载这个Assembly。

c) 引入变量:通过IronPython的“import”或“from ... import ...”语法,将你需要使用的类型引入当前Scope。

之后,你就可以使用类似“x = Form()”语法构建一个对象或通过类似“Color.Red”的语法访问对象的静态成员。

最后,给一个比较复杂的例子,从中可以理解一下IronPython的语法。

1

731655954c7be9d8835ece551b5385f8.pngimportclr2731655954c7be9d8835ece551b5385f8.pngclr.AddReference("System.Windows.Forms")3731655954c7be9d8835ece551b5385f8.png4731655954c7be9d8835ece551b5385f8.pngfromSystem.Windows.FormsimportForm5731655954c7be9d8835ece551b5385f8.pngfromSystem.Windows.FormsimportButton6731655954c7be9d8835ece551b5385f8.pngfromSystem.Windows.FormsimportDockStyle7731655954c7be9d8835ece551b5385f8.png8731655954c7be9d8835ece551b5385f8.pngform=Form()9731655954c7be9d8835ece551b5385f8.pngbutton=Button()10731655954c7be9d8835ece551b5385f8.pngbutton.Text="http://cajon.cnblogs.com"11731655954c7be9d8835ece551b5385f8.pngbutton.Dock=DockStyle.Fill12731655954c7be9d8835ece551b5385f8.pngform.Controls.Add(button)13731655954c7be9d8835ece551b5385f8.pngform.ShowDialog()

运行效果:

646adac3af09d5bed77608e5f32ed890.png

需要说明一下,因为在控制台上输入的脚本都是在同一个Scope对象上运行的,因此,import语句只需要运行一次就可以了。也就是说,上面的代码执行后,你可以继续使用Form、Button等类型。

4. 总结

微软在DLR和CLR之间交互方面的考虑很多,因此,对一些简单的操作,我们甚至感觉不到CLR对象和一个IronPython对象之间的区别。当然,动态语言的优势即在于它的动态类型系统,这一点和CLR的静态类型系统有很大的差别。因此很多IronPython的特性(例如:动态添加属性到对象上)无法在CLR对象上使用。在后面的章节中,我们将通过一些扩展接口实现更高级的嵌入。

另一方面,将方法注册到动态语言运行环境中也是大家比较关心的一个话题。虽然,通过注册对象到运行环境,已经可以在脚本中访问这些对象的方法。但毕竟不如直接使用方法来的简单。下一节将会详细的讨论相关的实现。敬请关注

icon_sub_c1s16_d.gif

e08c9898b71d6b105271e7778b7e2481.png

免责声明:本系列文章,完全是我个人研读IronPython源代码后找到的实现方案,并未详细的研究过IronPython的相关官方文档。因此,并不保证符合微软DLR和IronPython的设计思路,亦不能保证 在DLR和IronPython 2.0正式发布后能够继续使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值