【cocos2d-x从c++到js】JS与C++的交互1——JS代码调用C++代码

前端之家收集整理的这篇文章主要介绍了【cocos2d-x从c++到js】JS与C++的交互1——JS代码调用C++代码前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

我们要通过SpiderMonkey引擎的注册接口,向SpiderMonkey注册相应的从C++到JS的绑定函数,这些函数用于把JS函数调用代码转换成对应C++函数调用来执行。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//在AppDelegate::applicationDidFinishLaunching函数中@H_404_56@
@H_404_56@ ScriptingCore* sc = ScriptingCore::getInstance();@H_404_56@
sc->addRegisterCallback(register_all_cocos2dx);@H_404_56@
sc->addRegisterCallback(register_all_cocos2dx_extension);@H_404_56@
sc->addRegisterCallback(register_cocos2dx_js_extensions);@H_404_56@
sc->addRegisterCallback(register_all_cocos2dx_extension_manual);@H_404_56@
sc->addRegisterCallback(jsb_register_chipmunk);@H_404_56@
sc->addRegisterCallback(JSB_register_opengl);@H_404_56@
sc->addRegisterCallback(jsb_register_system);@H_404_56@
sc->addRegisterCallback(MinXmlHttpRequest::_js_register);@H_404_56@
sc->addRegisterCallback(register_jsb_websocket);@H_404_56@
sc->addRegisterCallback(register_all_cocos2dx_builder);@H_404_56@
sc->addRegisterCallback(register_CCBuilderReader);@H_404_56@
sc->addRegisterCallback(register_all_cocos2dx_gui);@H_404_56@
sc->addRegisterCallback(register_all_cocos2dx_gui_manual);@H_404_56@
sc->addRegisterCallback(register_all_cocos2dx_studio);@H_404_56@
sc->addRegisterCallback(register_all_cocos2dx_studio_manual);@H_404_56@
@H_404_56@
sc->addRegisterCallback(register_all_cocos2dx_spine);@H_404_56@


可以看到上面导入了Cocos2d-x的各种库,核心库,扩展,opengl,物理引擎,websocket,CCB等等等等。

下面我们说JS代码如何调用C++代码

首先,在创建JS对象的时候,也会创建一个对应的C++对象。换句话说,JS对象是和C++对象一一对应的(当然必须是引擎支持的,而且绑定了接口的)。然后,在JS对象执行函数时,发生了什么呢?SpiderMonkey引擎会通过注册的接口,找到对应的C++对象,调用该对象上对应的C++函数

换句话说,如果有下面的JS代码:

2
var@H_404_56@ node = cc.Node.create();@H_404_56@
node.setVisible(@H_404_56@ false@H_404_56@ );@H_404_56@

那么经过SpiderMonkey执行后,会调用下面的代码

auto@H_404_56@ node = CCNode::create();@H_404_56@
node->setVisible(@H_404_56@ false@H_404_56@ 当然,SpiderMonkey远远还不止干了这些,还做了很多事,比如绑定和查找JS和C++对象的对应关系,包装参数为对应类型,类型安全检查,返回值包装等等。要知道他干了些什么,直接看引擎代码是更好的选择。

在Cocos2d-x 3.0版的引擎中,引擎目录结构进行了大规模重构。

两个脚本语言被放到一个类似的目录中。其中auto-generated/js-bindings文件夹是gxx-generator工具自动生成的所有C++绑定JS代码。而JavaScript/bingdings文件夹是手写的绑定代码,因为工具无法做到完全自动绑定,所以必须有一部分手写的(脚本语言都是这样,习惯就好了,谢谢)。

好,我们继续找刚才说的源代码。打开jsb_cocos2dx_auto.cpp

19
JSBool js_cocos2dx_Node_create(JSContext *cx,uint32_t argc,jsval *vp)@H_404_56@
{@H_404_56@
@H_404_56@ if@H_404_56@ (argc == 0) {@H_404_56@
cocos2d::Node* ret = cocos2d::Node::create();@H_404_56@
jsval jsret = JSVAL_NULL;@H_404_56@
do@H_404_56@ {@H_404_56@
(ret) {@H_404_56@
js_proxy_t *proxy = js_get_or_create_proxy<cocos2d::Node>(cx,(cocos2d::Node*)ret);@H_404_56@
jsret = OBJECT_TO_JSVAL(proxy->obj);@H_404_56@
}@H_404_56@ else@H_404_56@ {@H_404_56@
jsret = JSVAL_NULL;@H_404_56@
}@H_404_56@
while@H_404_56@ (0);@H_404_56@
JS_SET_RVAL(cx,vp,jsret);@H_404_56@
return@H_404_56@ JS_TRUE;@H_404_56@
}@H_404_56@
JS_ReportError(cx,@H_404_56@ "js_cocos2dx_Node_create : wrong number of arguments"@H_404_56@ );@H_404_56@
JS_FALSE;@H_404_56@
}@H_404_56@

这就是cc.Node.create()执行时,底层C++跑的代码。所有的通过JS调用C++的代码都与这个形式非常一致,首先看函数接口:

第一个参数JSContext *cx是JS的上下文

第二个参数uint32_t argc是JS代码中的参数个数,在这个里argc==0

第三个参数jsval *vp是JS代码中的具体参数

继续分析

1
cocos2d::Node* ret = cocos2d::Node::create();@H_404_56@

这个代码再熟悉不过了,标准的Cocos2d-x静态工场生成对象的代码

jsval jsret = JSVAL_NULL;@H_404_56@

jsval jsret是这个函数的返回值,这是表示的是一个JS对象

Highlighter_472528" class="SyntaxHighlighter cpp" style="width:720px; padding:0px!important; margin:0.3em 0px!important; border:0px!important; bottom:auto!important; float:none!important; left:auto!important; line-height:1.1em!important; outline:0px!important; overflow-y:visible!important; overflow-x:auto!important; position:relative!important; right:auto!important; top:auto!important; vertical-align:baseline!important; font-family:Consolas,(cocos2d::Node*)ret);@H_404_56@
jsret = OBJECT_TO_JSVAL(proxy->obj);@H_404_56@

注意这个模板函数,get_or_create,这就是把JS对象和C++对象绑到一起的函数。他非常重要,注意JS和C++对象是一一对应关系,理解这个特效,有助于我们利用JS语言的动态性进行更方便的编程。绑完之后,下面那个函数是用于获得返回值。

最后,函数都要返回一个JSBool,表面这个函数执行是否成功。如果返回JS_FALSE,还会通过JS_ReportError打印一条报错信息。注意!脚本语言有一个特点,如果函数运行失败了,则该函数后面的函数(在同一作用域中的)都会跳过执行。


继续看下一个函数

19
JSBool js_cocos2dx_Node_setVisible(JSContext *cx,jsval *vp)@H_404_56@
{@H_404_56@
@H_404_56@ jsval *argv = JS_ARGV(cx,vp);@H_404_56@
JSBool ok = JS_TRUE;@H_404_56@
JSObject *obj = JS_THIS_OBJECT(cx,vp);@H_404_56@
js_proxy_t *proxy = jsb_get_js_proxy(obj);@H_404_56@
cocos2d::Node* cobj = (cocos2d::Node *)(proxy ? proxy->ptr : NULL);@H_404_56@
JSB_PRECONDITION2( cobj,cx,JS_FALSE,@H_404_56@ "js_cocos2dx_Node_setVisible : Invalid Native Object"@H_404_56@ );@H_404_56@
@H_404_56@ if@H_404_56@ (argc ==@H_404_56@ 1@H_404_56@ ) {@H_404_56@
JSBool arg0;@H_404_56@
ok &= JS_ValueToBoolean(cx,argv[@H_404_56@ 0@H_404_56@ ],&arg0);@H_404_56@
JSB_PRECONDITION2(ok,monospace!important; font-size:1em!important; min-height:inherit!important; color:blue!important">"js_cocos2dx_Node_setVisible : Error processing arguments"@H_404_56@ );@H_404_56@
cobj->setVisible(arg0);@H_404_56@
404_56@
return@H_404_56@ JS_TRUE;@H_404_56@
}@H_404_56@
"js_cocos2dx_Node_setVisible : wrong number of arguments: %d,was expecting %d"@H_404_56@ ,argc,@H_404_56@ );@H_404_56@
JS_FALSE;@H_404_56@
这个函数和前一个函数的区别是,这个函数有参数,并且他是一个类成员函数(上一个是类静态函数),所以,这里要有this指针。

6
404_56@
JSBool ok = JS_TRUE;@H_404_56@
404_56@
js_proxy_t *proxy = jsb_get_js_proxy(obj);@H_404_56@
cocos2d::Node* cobj = (cocos2d::Node *)(proxy ? proxy->ptr : NULL);@H_404_56@
"js_cocos2dx_Node_setVisible : Invalid Native Object"@H_404_56@ 这一大段函数都在找那个this指针。注意,这里面有一个Cocos2d-x引擎经常出现的错误提示Invalid Native Object。底层C++对象被回收了,所以找不到了。

8
(argc == 1) {@H_404_56@
JSBool arg0;@H_404_56@
404_56@
"js_cocos2dx_Node_setVisible : Error processing arguments"@H_404_56@ );@H_404_56@
cobj->setVisible(arg0);@H_404_56@
404_56@
JS_TRUE;@H_404_56@
CCNode::setVisible(xx)只有一个参数,所以先判断JS的参数个数为1。JS_ValueToBoolean完成JS对象到C++对象的转换,注意!这是基本类型的转换,和查找对应的对象指针不同。你在gxx-generator生成代码中会看到大量的这种转换。每次转换都要进行结果判断,如果失败,就打印错误信息。后面是直接调用对应C++对象的setVisible,以及设置返回值。

很繁琐不是吗?如果这种代码全部手写是不是会死人呢。肯定的吧。所以这些代码都是用脚本生成器做出来的(绝大部分)。

后面我们会继续讲解各种JS的绑定代码

来自:http://blog.csdn.net/kaitiren/article/details/22163193

原文链接:https://www.f2er.com/cocos2dx/339310.html

猜你在找的Cocos2d-x相关文章