`
pascal4123
  • 浏览: 114650 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

为Delphi应用增加脚本支持(ZT)

    博客分类:
  • GP
阅读更多
来源 http://www.cnblogs.com/sephil/archive/2012/02/23/mssc.html


上次说到我想为DirectUI增加脚本支持,今天我们就来研究下脚本的实现问题。

虽然现在有了诸如AntLR、GOLD Parser、TP Lex and Yacc等等CC工具,大大方便了脚本引擎的开发,但我仍然觉得在这个框架里自己实现一套脚本引擎是件毫无意义的事。所以我决定使用现有的脚本引擎。

事实上Delphi可用的第三方脚本引擎很多,这里列几个常见的:

FastScript

    号称最快的Delphi脚本引擎,支持 VB、JS、Cpp、Pascal 语法,可以在脚本中使用自定义的类型和对象,内置了对Delphi VCL的支持。

ifps/RemObjects PascalScript

    使用Pascal语法的脚本引擎,可以在脚本中使用自定义的类型和对象。

TMS Scripter Studio

    TMS出品的脚本引擎,除了脚本引擎,还附带有一堆可视控件,可以用来开发IDE。

    支持在脚本中使用自定义的类型和对象,也内置了对Delphi VCL的支持。

PaxScript / PaxCompiler

    这是我用过的Delphi里最强大的脚本引擎了。同样,她支持 VB、JS、Cpp、Pascal 语法,也支持在脚本中使用自定义的类型和对象,内置了对Delphi VCL的支持。

    另外,她还支持将脚本代码编译成中间字节码,以后运行是可以直接载入中间字节码执行,节约了代码解析的时间。如果使用PaxCompiler,你甚至可以将脚本代码编译成机器码直接执行!

但是最终我并没有在其中进行选择,因为上述这些脚本引擎都有一个问题,就是对自定义的类型和对象的支持方式。

在这些引擎中,如果你要增加自定义类型的支持,就必须为每一个类的每一个方法和属性生成一个代理函数,然后通过引擎通过这些代理函数对对象进行操作。

想想我的DirectUI引擎,其中大大小小有上百个类,光生成这些代理函数都能让我疯了。虽然它们也有提供工具,可以根据源代码直接生成代理函数,但问题是我以后如果修改了源代码,岂不是又得重新生成一遍?想想都烦啊。

最后我把目光定在了MS身上。其实MS早就为我们提供了一套好用的脚本引擎:MS ScriptControl。见过HTML里的VBS和JS吗?那里用的脚本引擎跟MS ScriptControl是同一套核心。

MS ScriptControl系统默认支持VBS和JS,但实际上他的语法是可以扩展的。例如你机器上如果装有Python,你就能在脚本中使用Python。

MS ScriptControl可以访问自动化对象(对应到Delphi里就是TAutoObject),将对象用AddObject方法注册到引擎里,就可以在脚本中访问了。在运行时,引擎会取得对象的IDispatch接口实现,并通过IDispatch.GetIDsOfNames取得要访问的方法或属性的ID,然后在调用IDispatch.Invoke执行此方法或取得此属性的值。

聪明的你一定想到了,我只要实现一个TAutoObject代理对象,然后用这个对象通过RTTI,就可以访问到我们的自定义对象了!借助RTTI,我只需要实现一个通用的代理对象,就能让脚本访问所有类型的对象,即使类型有更改,代理对象都不需要做任何改动!真正的一劳永逸啊,哇咔咔~~~







好了,饭要一口一口吃,现在我们先把MS ScriptControl封装一下,后面再去做代理对象。

我们先来定义一套接口,这套接口定义了我们的脚本引擎所需要实现的功能,然后再封装MS ScriptControl来实现。这样做的好处是,如果我以后想换其他的脚本引擎,只需要把这套接口重新实现一遍就好了,外部调用脚本引擎的地方基本无需改动。

代码不贴上来了,后面有下载。



这里还要说说MS ScriptControl的一些东西。其实网上相关的文章不少,不过大多都是泛泛而谈,有用的东西不多,我只好自己研究了。

简单的东西就不写了,去google吧,这里讲几个网上找不到相关说明的细节。

MS ScriptControl中有模块的概念,就像我们IDE中同一工程下不同的单元文件一样。默认有一个主模块,名字叫Global,MS ScriptControl中的AddCode、Eval、ExecuteStatetment等方法都是对这个模块访问的封装。其他模块是需要用Modules.Add自己添加的。

这里有个细节,Modules.Add方法有2个参数:Name,模块名称,必填;Obj,OleVariant类型,是个可选参数。这个参数做什么用的我到现在也没明白,本来我也不想关心他的,可惜绕不过去。在VB中,DispInterface的可选参数可以不写,直接Modules.Add("Module1")就OK,可是Delphi下这个参数是var的,必须填。于是我
复制代码
var
  Obj: OleVariant;
begin
  Obj := Unassigned;
  Modules.Add('Module1', Obj);
end;
复制代码

运行报错。。。于是我再Obj := Null,错。。。再Obj := 0,又错。。。数次失败后,我都快绝望了。。。后来我想,这个参数我也不用,不是有个全局的EmptyParam么,省了我声明个变量,于是Modules.Add('Module1', EmptyParam),结果。。。通过了。。。神那,你能告诉我这参数到底干虾米用的啊。。。泪啊。。。



继续。。。与编译器对待单元文件的方式不同,这些模块都是封闭的,除了其他的模块可以直接调用主模块中方法外,其他模块之间无法直接互相调用,主模块也无法调用其他模块。挺奇怪的。

后来我想了个辙。每个模块都有个属性CodeObject,即该模块的代码对象,通过他是可以调用到模块中的代码的。这个对象可是IDispatch哦,那么我将他注册到脚本引擎里,不就可以在其他模块中用 模块名.对象 来访问了吗?我真是太聪明了,咔咔。。。于是乎,就有了下面的代码
复制代码
var
  I: Integer;
  Module: IScriptModule;
begin
  for I := 1 to Modules.Count do
  begin
    Module := Modules[I];
    FScript.AddObject(Module.Name, Module, False);
  end;
end;
复制代码

F5,嗯,出错?对象名已存在??NN个熊,要存在我怎么访问不到!算了,只好出昏招,我注册名跟模块名不一样,总可以了吧。。。



唉,折腾了一天,总算是可以用了~

图上是调用第一个模块的Foo方法的执行结果



好了,罗罗嗦嗦了这么多,就到这里吧,下次再来实现代理对象。
分享到:
评论

相关推荐

    Delphi支持多种脚本语言演示.rar

    这个名为"Delphi支持多种脚本语言演示.rar"的压缩包显然旨在展示如何在Delphi环境中集成和调试多种脚本语言,包括Python、Lua、PHP和Perl。 首先,Python是一种广泛使用的解释型、面向对象的编程语言,具有简洁清晰...

    Delphi实现脚本引擎

    5. **集成到Delphi应用**:将脚本引擎作为Delphi组件,使其能够被其他Delphi应用程序所使用。这可能涉及到接口设计、事件处理和通信机制。 6. **调试与测试**:实现调试功能,如断点、单步执行、变量查看等,确保...

    delphi调用lua脚本的一个例子

    Delphi是一款强大的Object Pascal集成开发环境(IDE),而Lua则是一种轻量级、高效的脚本语言,常用于游戏开发和其他需要嵌入式脚本的应用程序。将两者结合,我们可以利用Delphi的底层性能和Lua的易用性来构建复杂...

    在delphi中嵌入脚本语言

    在Delphi中嵌入脚本语言是一项常见的技术需求,它允许开发者通过脚本代码扩展应用程序的功能,而无需重新编译整个程序。这种技术通常应用于那些需要动态配置、自定义行为或者用户可编程接口的系统中。本文将深入探讨...

    Delphi 脚本开发框架

    总之,Delphi脚本开发框架结合了Delphi的强大编程能力和脚本语言的灵活性,为开发者提供了一个高效、易用的工具,用于创建具有高度自定义界面和动态脚本功能的应用程序。通过深入理解和熟练运用这个框架,开发者可以...

    delphi TImage 增加支持 png 图片格式 TPNGImage

    TPNGImage 是一个专门为 Delphi 开发的 PNG 图像处理组件,它为 Delphi 的 VCL(Visual Component Library)框架添加了对 PNG 图像格式的支持。这个组件由第三方开发者创建,提供了高效且功能丰富的 PNG 图像处理...

    delphi script 脚本 TMS Scripter d7-xe10源码

    Delphi Script是一种基于Delphi编译器的脚本语言,主要设计用于在Delphi应用程序中嵌入和执行脚本代码。TMS Scripter是针对Delphi开发者的一个强大的工具,它提供了一个全面的脚本环境,使得开发人员能够在Delphi 7...

    脚本delphi脚本

    Delphi脚本是一种基于Object Pascal语言的脚本技术,它被广泛应用于开发Windows桌面应用程序。Delphi是一款由Embarcadero Technologies(之前是Borland)开发的集成开发环境(IDE),它以其高效的编译器和强大的VCL...

    delphi使用lysee脚本的例子(windows下)

    通过引入Lysee的库和API,开发者可以在Delphi程序中执行、编写和管理Lysee脚本,增加程序的灵活性和可扩展性。 2. **Lysee脚本语言基础**:Lysee拥有类似于Perl或Ruby的语法,支持面向对象编程,包括类、继承、封装...

    delphi脚本开发框架

    Delphi脚本开发框架是一种基于Delphi编程环境的高级开发工具,它允许开发者在应用程序中集成自定义的脚本语言,以实现动态行为和逻辑控制。这个框架将Delphi的强类型编译器特性和脚本语言的灵活性相结合,极大地提高...

    DELPHI SynEdit 代码编辑器 支持HTML,C#,JAVA,DELPHI 多脚本语法识别,高亮,查找,功能强大

    **DELPHI SynEdit 代码编辑器:多脚本语法识别与高级功能** SynEdit是专为DELPHI开发者设计的一款强大的代码编辑器组件。它不仅支持多种编程语言的语法高亮显示,如HTML、C#、JAVA和DELPHI,而且提供了丰富的编辑...

    《数据库应用技术——Delphi应用系统开发》-蒋丽华-电子教案

    同时,Delphi支持数据库脚本的编写和执行,便于数据库的迁移和同步。 在项目开发过程中,理解Delphi的事件驱动编程模型至关重要。每个控件都有自己的事件,通过编写事件处理函数,我们可以响应用户操作或其他系统...

    delphi google V8 脚本引擎接口 delphi程序 最佳 javascript 途径

    标题中的“delphi google V8 脚本引擎接口 delphi程序 最佳 javascript 途径”指的是一项技术实践,即在Delphi编程环境中利用Google的V8 JavaScript引擎创建脚本接口,以实现高效的JavaScript交互。V8是Google开发的...

    pythontodelphi 控件python4delphi 实现delphi调用python 脚本

    总结来说,`Pythontodelphi`和`Python4Delphi`为Delphi开发者提供了与Python脚本的无缝集成,让Delphi项目能够方便地利用Python的广泛库和功能,极大地扩展了Delphi的应用范围。通过理解并熟练使用这些工具,开发者...

    支持中文函数名中文变量名的delphi脚本语言

    5. **支持**:表示这个Delphi脚本引擎具备了上述中文命名的功能,为开发者提供了更多的灵活性。 在"压缩包子文件的文件名称列表"中,虽然没有具体文件的详细信息,但我们可以推测其中可能包含源代码、示例、文档...

    delphi中的脚本控件paxscript3.0

    TPaxScripter for Delphi 5, 6, 7, 2005, BCB 5, BCB 6, Kylix 3. ------------------------------------------------------------------------------ Version: 3.0. Build: 29 May, 2006. Copyright (c) 2003-2006 ...

    delphi应用开发完全手册

    《Delphi应用开发完全手册》是一本专注于使用Embarcadero Delphi进行应用程序开发的全面指南。这本书旨在帮助开发者从初学者到高级水平,通过详细讲解Delphi编程语言和RAD(快速应用程序开发)环境,掌握高效的应用...

    delphi 自定义表到脚本编辑器

    "delphi 自定义表到脚本编辑器"的主题涉及到了将Delphi与脚本编辑功能相结合,为开发者提供了一个创新的解决方案,使他们能够为自己的应用程序添加更丰富的交互性和动态性。 首先,让我们深入了解Delphi Scripter。...

Global site tag (gtag.js) - Google Analytics