一种脚本引擎接口抽象层及其应用方法与流程

文档序号:16066851发布日期:2018-11-24 12:45阅读:291来源:国知局

本发明涉及计算机软件领域,尤其是一种脚本引擎接口抽象层及其应用方法。

背景技术

脚本绑定技术是指通过脚本引擎提供的接口将原生语言(c或c++)编写的类和方法注册到脚本层供脚本调用的一种技术。市面上主流的javascript脚本引擎有v8、javascriptcore、spidermonkey,chakracore,它们分别是chrome、safari、firefox、微软edge浏览器内嵌的javascript脚本引擎。不同脚本引擎提供的c++接口是不同的,甚至同一个脚本引擎在不同的版本提供c++接口也存在差异,这导致c++与脚本交互的绑定代码也存在很大差异。基于一种脚本引擎接口编写的绑定代码不可能通过简单的配置切换到其它脚本引擎,同一脚本引擎的不同版本也可能存在接口兼容问题导致无法轻松升级脚本引擎。

当一个应用在不同平台需要不同的脚本引擎时,比如安卓手机上使用v8引擎,苹果手机使用系统内嵌的javascriptcore引擎,现有技术方案有:

1、分别为不同平台使用不同的脚本引擎编写不一样的绑定代码,即需要多份绑定代码,维护成本翻倍,无法切换底层引擎。2018年初上线的微信小游戏采用此方案。

2、nodejs这个业界流行的开源库使用v8将一些c++编写的类型和方法注册到javascript脚本层中,开发者可以通过更易使用的javascript脚本语言编写复杂的客户端与服务端逻辑。微软chakracore团队通过node-chakracore项目成功地将nodejs的底层切换为chakracore。mozilla公司也使用类似方案(spidernode)将nodejs底层切换为spidermonkey脚本引擎。此类型的方案需要实现一套适配层,适配层的接口与v8引擎提供的接口完全一致,使用chakracore或者spidermonkey等非v8引擎提供的功能来适配v8的所有接口。这种方案的缺点为:1)需要用非v8引擎实现v8引擎的全部功能,实现逻辑较复杂。2)绑定代码的编写者需要深入了解复杂的v8引擎提供的接口,学习成本较高。3)未提供便捷方法快速切换脚本引擎。

3、noden-api:从nodejs8.0开始,node官方提供了一套n-api,n-api是一套抽象层接口,此抽象层接口不随着v8引擎接口的变化而变化,使用此api编写node插件的开发者无需因为node升级版本而修改绑定代码和重新编译插件,即插件的兼容性比nodejs8.0之前版本更高。此方案的缺点为:1)抽象层只适配了v8引擎,暂时无法适配其它脚本引擎;2)抽象层解决的问题是插件升级问题,并不是最优性能的方案,即脚本接口的调用需要通过一层代码中转才能调用到用户编写的回调函数,调用开销较大。



技术实现要素:

本发明一方面提供一种脚本引擎接口抽象层,包括宏模块、脚本与c++对象映射表、scriptengine模块、value模块、autohandlescope模块、class模块、state模块、object模块、handleobject模块,其中,

所述宏模块用于解决不同脚本引擎回调函数参数类型和返回值类型不同的问题,不管底层使用什么引擎,开发者使用同一种回调函数的定义方式,定义完回调函数后,需要使用se_bind_xxx系列的宏对回调函数进行包装;

所述脚本与c++对象映射表用于查询c++对象指针获取对应的脚本对象;

所述scriptengine模块用于掌管脚本引擎的初始化、销毁、重启、c++模块注册、加载脚本、强制垃圾回收、脚本异常清理以及是否启用调试器;

所述value模块为脚本变量在c++层的引用;

所述object模块保存了对脚本对象的弱引用;

所述handleobject模块是一个辅助类,用于更加简单地管理object模块中手动创建对象的释放、root和unroot操作;

所述class模块用于暴露c++类到脚本环境中,class类型创建后,不需要手动释放内存,其占用内存会被抽象层自动处理;

所述autohandlescope模块,其只在v8引擎上有实现,抽象层适配的其它脚本引擎目前都只是空实现这个类型;

所述state模块作为绑定回调中的一个上下文对象,通过state模块可以取得当前的c++对象指针、se::object对象指针、参数列表、返回值引用。

本发明另一方面提供一种脚本引擎接口抽象层的应用方法,设定脚本相关操作的c++回调函数,在回调函数中关联c++对象,具体步骤如下:

步骤1:获取namepace对象;

步骤2:创建se::class;

步骤3:为se::class定义属性与方法;

步骤4:注册se::class到脚本虚拟机中;

步骤5:获取se::class的proto对象;

步骤6:通过proto对象设置绑定类的静态属性与静态方法;

步骤7:清空异常。

本发明提供的一种脚本引擎接口抽象层及其应用方法,其有益效果在于:可轻松适配不同的javascript甚至其它非javascript脚本引擎,保证脚本语言与原生语言(c/c++)之间调用的性能不下降的同时,做到轻松切换或升级底层脚本引擎且不需要修改任何的绑定代码;本发明的抽象层设计更加高效,代码从脚本层调用到用户c++层的调用是通过宏的方式在绑定代码编译期间确定的,这个过程不存在中转分发;抽象层接口采用面向对象的设计,接口简洁,包括了scriptengine,class,value,object,handleobject,state,autohandlescope这几种数据类型模块,满足编写绑定代码需要的所有功能,支持市面上主流的javascript脚本引擎。

附图说明

图1是本发明的脚本引擎接口抽象层模块图;

图2是本发明的脚本引擎接口抽象层的应用框架图;

图3是本发明的脚本引擎接口抽象层的应用流程图。

具体实施方式

为进一步说明各实施例,本发明提供有附图。这些附图为本发明揭露内容的一部分,其主要用以说明实施例,并可配合说明书的相关描述来解释实施例的运作原理。配合参考这些内容,本领域普通技术人员应能理解其他可能的实施方式以及本发明的优点。图中的组件并未按比例绘制,而类似的组件符号通常用来表示类似的组件。

现结合附图和具体实施方式对本发明进一步说明。

如图1所示,本实施例提供的脚本引擎接口抽象层,包括宏模块、脚本与c++对象映射表、scriptengine模块、value模块、autohandlescope模块、class模块、state模块、object模块、handleobject模块,其中,

宏模块用于解决不同脚本引擎回调函数参数类型和返回值类型不同的问题,不管底层使用什么引擎,开发者使用同一种回调函数的定义方式,定义完回调函数后,需要使用se_bind_xxx系列的宏对回调函数进行包装。脚本引擎抽象层提供了如下几个宏:

se_bind_prop_get宏:包装脚本对象属性读取的回调函数;

se_bind_prop_set宏:包装脚本对象属性写入的回调函数;

se_bind_func宏:包装脚本函数,可用于全局函数、类成员函数、类静态函数;

se_declare_func宏:声明脚本函数,一般在.h头文件中使用;

se_bind_ctor宏:包装脚本构造函数;

se_bind_sub_cls_ctor宏:包装脚本子类的构造函数;

se_finalize_func宏:包装脚本对象被垃圾回收后的回调函数;

se_declare_finalize_func宏:声明脚本对象被垃圾回收后的回调函数;

_se宏:用于包装回调函数的名称,其可以将开发者编写的基于抽象层的通用回调函数转义为每个脚本引擎能够识别的回调函数的定义。

脚本与c++对象映射表用于查询c++对象指针获取对应的脚本对象。

scriptengine模块为脚本引擎的管理员,用于掌管脚本引擎的初始化、销毁、重启、c++模块注册、加载脚本、强制垃圾回收、脚本异常清理以及是否启用调试器。

value模块为脚本变量在c++层的引用,javascript的脚本变量类型有object、number、string、boolean、null、undefined这六种类型,因此value模块使用union包含object、number、string、boolean这四种有值类型,无值类型null,undefined可由value模块中的_type变量直接表示,如果value模块中保存的是基础数据类型,比如number、string或者boolean,value模块内部是直接存储一份值副本,本实施例的value模块的内部成员布局如下:

object模块保存了对脚本对象的弱引用,采用弱引用的原因如下:

1、脚本对象控制c++对象的生命周期的需要,当在脚本层中通过类似varsp=newcc.sprite("a.png");的方法创建了一个绑定对象后,在构造回调函数绑定中我们会创建一个object模块并保留在一个全局的映射表中;

2、弱引用更加灵活,但也可通过手动调用root方法支持强引用,root会把脚本对象放入到不受垃圾回收器扫描到的区域,调用root后,object模块就强引用了脚本对象,只有当unroot被调用,或者object模块被释放后,脚本对象才会被放回到受垃圾回收器扫描到的区域。

object模块除了支持创建绑定对象,还支持以下几种非绑定对象类型的手动创建:

plainobject:通过se::object::createplainobject创建,类似javascript中的vara={};

arrayobject:通过se::object::createarrayobject创建,类似javascript中的vara=[];

typedarrayobject:通过se::object::createtypedarray创建,类似javascript中的vara=newuint8array(buffer);

arraybufferobject:通过se::object::createarraybufferobject,类似javascript中的vara=newarraybuffer(len)。

handleobject模块是一个辅助类,用于更加简单地管理object模块中手动创建对象、root和unroot操作。

class模块用于暴露c++类到脚本环境中,class类型创建后,不需要手动释放内存,会被抽象层自动处理,其中class类型创建方法如下:

staticse::class*create(classname,obj,parentproto,ctor):创建一个class,注册成功后,在javascript层中可以通过varxxx=newsomeclass();的方式创建一个对象;

booldefinefunction(name,func):定义class中的成员函数;

booldefineproperty(name,getter,setter):定义class属性读写器;

booldefinestaticfunction(name,func):定义class的静态成员函数,可通过someclass.foo()这种非new的方式访问,与类实例对象无关;

booldefinestaticproperty(name,getter,setter):定义class的静态属性读写器,可通过someclass.propertya直接读写,与类实例对象无关;

booldefinefinalizefunction(func):定义脚本对象被垃圾回收后的c++回调;

boolinstall():注册此类到脚本虚拟机中;

object*getproto():获取注册到脚本中的类的prototype对象,类似functionfoo(){}的foo.prototype;

constchar*getname()const:获取当前class的名称。

autohandlescope模块,其只在v8引擎上有实现,抽象层适配的其它脚本引擎目前都只是空实现这个类型,是因为v8引擎中,当有c++函数中需要触发脚本相关操作,比如调用脚本函数,访问脚本属性等任何调用v8::local<>的操作,v8强制要求在调用这些操作前必须存在一个v8::handlescope作用域,否则会引发程序崩溃。在任何c++代码执行中,需要调用javascript的逻辑前,声明一个autohandlescope模块即可,比如:

state模块作为绑定回调中的一个上下文对象,通过state模块可以取得当前的c++对象指针、se::object对象指针、参数列表、返回值引用。

如图2所示,本实施例提供的脚本引擎接口抽象层,作为不同脚本引擎与采用脚本语言编写的游戏或应用的之间一个桥梁,本实施例的抽象层不依赖于特定脚本引擎,基于此抽象层编写的脚本绑定代码不需要经过任何修改,只通过一个简单的宏配置即可实现底层脚本引擎轻松切换或升级。

javascriptcore,spidermonkey,v8,chakracore四种脚本引擎绑定函数的定义各不相同,具体如下:

如图3所示,本实施例提供的脚本引擎接口抽象层的应用方法大部分工作是设定脚本相关操作的c++回调函数,在回调函数中关联c++对象,具体绑定方法如下:

步骤1:获取namepace对象;

步骤2:创建se::class;

步骤3:为se::class定义属性与方法;

步骤4:注册se::class到脚本虚拟机中;

步骤5:获取se::class的proto对象;

步骤6:通过proto对象设置绑定类的静态方法与静态属性;

步骤7:清空异常。

本发明提供的脚本引擎接口抽象层,可轻松适配不同的javascript甚至其它非javascript脚本引擎,保证脚本语言与原生语言(c/c++)之间调用的性能不下降的同时,做到轻松切换或升级底层脚本引擎且不需要修改任何的绑定代码;本发明的抽象层设计更加高效,代码从脚本层调用到用户c++层的调用是通过宏的方式在绑定代码编译期间确定的,这个过程不存在中转分发;抽象层接口采用面向对象的设计,接口简洁,包括了scriptengine,class,value,object,handleobject,state,autohandlescope这几种数据类型模块,满足编写绑定代码需要的所有功能,支持市面上主流的脚本引擎。

尽管结合优选实施方案具体展示和介绍了本发明,但所属领域的技术人员应该明白,在不脱离所附权利要求书所限定的本发明的精神和范围内,在形式上和细节上可以对本发明做出各种变化,均为本发明的保护范围。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1