数以执行动态脚本
1. 使用CREATE USING objecttypestring语句创建对象
2. 通过动态调用对象的of_exec函数执行动态脚本,区分返回值类型
六.销毁所有临时对象
1. 调用LibraryDelete函数删除创建的临时库文件
以下讲我在开发时遇到的一些矛盾或问题。
一.代码是逐行解释还是让PB编译器去解释
有些开发人员试图对动态脚本自行逐行解释,这是很困难的事情。一行代码如果脱离它的语境去执行,可能会产生错误的结果,即便你对PB所支持的函数全部做出解释,使用PB开发出来的对象、函数、事件等,你又如何去解释?这等同于你要花很大力气去编写一个PB编译器,除非你与PB编译器的开发团队合作,否则你很难获得成功。所以你必须想办法让PB编译器去解释。既然每行代码不能脱离其它代码而执行,那就创建一个函数或事件,让这个函数或事件包括你想写的所有代码。而函数或事件又不能脱离对象而存在,所以你必须想办法动态创建对象以及函数或事件,对象的声明必须依赖于库文件中的PB实体,由此推出关键是创建PB实体。
二.如何创建PB实体
前面已讲过要使用PBORCX0.DLL中的WINAPI函数来创建并导入实体,这项技术并不难,在sybase的网站或随便狗狗(百度)一下就能出来一大把。
三.创建的PB实体是存放在现有库文件中还是新文件中再导入
我最初的想法是放在现有库文件中,这样就不必花费时间在创建库文件和删除库文件的执行上,结果发现,创建是成功,但运行时PB就是不“认识”我创建的PB实体,一创建该实体的对象就报错,想来PB在程序
启动时就读取库文件中有哪些实体形成列表,在没有改变库文件列表之前,其实体列表不会改变,这样对新建的实体就视而不见了。所以我不得不试着新建一个PBL,在新建的PBL中创建PB实体,然后使用AddToLibraryList将新建的PBL包括进来,这一试果然成功。
四.使用数据窗口的Describe调用全局函数还是其它方式来取得返回值
大家都知道,使用数据窗口的Describe函数可以调用全局函数,但是它有很多的局限性,全局函数必须有简单类型的返回值,所有参数只能是简单数据类型而且不能通过参考传值。如果在需要调用的地方直接使用新建对象的函数将不受这些限制。
五.如何进行垃圾对象的清理
既然每次执行动态脚本要创建PB实体,如果执行得多了,就有很多垃圾对象,所以应进行清理。可以通过LibraryDelete函数或FileDelete删除库文件。有意思的是,一旦创建PB实体,即便你删除了,使用FindClassDefinition或FindFunctionDefinition还是能够找到,但你想使用该实体创建对象则失败,这再次说明PB在程序启动时就读取库文件中有哪些实体形成列表,在没有改变库文件列表之前,其实体列表不会改变。
以下是所附代码的几点说明
一.所附代码是在PB9环境下开发的,
程序运行时必须有PBORC90.DLL,如果改成PB其它版本,请将nvo_pbcompiler中WINAPI函数所使用的动态库做相应修改。
二.nvo_pbcompiler用于创建PB实体,这是PB动态脚本解释器的核心函数;f_execpbscript()用于执行一段PB脚本的样例代码函数,返回值类型为字符串,如果要使用到其它场合,读者可自行编写函数,思路类似;w_pbcompiler_test为一个用来执行PB脚本的样例界面窗口;其它函数有各自功能。
三.如果想运行PB动态脚本编译器,请先将所有代码分对象导入库文件,然后编译,PB动态脚本编译器在PB开发环境下无效。
四.为了程序方面的简化,有些所使用的全局函数请参考作者的其它文章。
五.所附代码仅为脚本没有参数的情况下有效,如果你想代码有参数,只需要简单地对脚本语法作些改变就可,当然前台需要用户定义参数。
六.本PB动态脚本解释器可执行所有有效的PB代码,