一,示例js绑定c++的过程,实现在js中设定应用程序的“设计分辨率”以及在c++中调用js脚本。
二,手动绑定入口
新建一个.h文件,此处定义为“JsbUtil.h”,定义函数:void register_jsb_util(JSContext *cx, JSObject *global);
参数含义简介:
cx:
几乎所有的js api都要求我们传递一个上下文做为参数。在cocos2d-x中的js上下文在类ScriptingCore中定义:rt_。它就像是一台小机器,它涉及JavaScript代码和对象的很 多东西。它可以编译和执行脚本、获取和设置对象属性、调用JavaScript函数、一种类型转换为另一种JavaScript数据、创建对象,等等。
global:
全局js对象,全局对象包含所有可以在JavaScript代码中使用 的类、函数和变量。
三,实现绑定入口函数
新建一个.cpp文件,此处命名为“JsbUtil.cpp”。
首先声明两个变量:
JsClass *js_util_class; //要和c++绑定的js类
JsObject *js_util_prototype; //在创建上述class类时的原型
第二步中声明函数的实现如下:
-
-
-
-
-
-
-
-
- void register_jsb_util(JSContext *cx, JSObject *global)
- {
-
-
- js_util_class = (JSClass*)calloc(1, sizeof(JSClass));
- js_util_class->name = "APP_UTIL";
- js_util_class->addProperty = JS_PropertyStub;
- js_util_class->delProperty = JS_PropertyStub;
- js_util_class->getProperty = JS_PropertyStub;
- js_util_class->setProperty = JS_StrictPropertyStub;
- js_util_class->enumerate = JS_EnumerateStub;
- js_util_class->resolve = JS_ResolveStub;
- js_util_class->convert = JS_ConvertStub;
- js_util_class->finalize = js_utility_finalize;
-
-
- js_util_class->flags = JSCLASS_HAS_RESERVED_SLOTS(2);
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- static JSPropertySpec properties[] = {
- {0, 0, 0, 0, 0}
- };
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- static JSFunctionSpec funcs[] = {
- JS_FN("setDesignResolution", js_util_set_design_resolution, 3, JSPROP_ENUMERATE|JSPROP_PERMANENT),
- JS_FS_END
- };
-
-
-
-
-
-
- static JSFunctionSpec st_funcs[] = {
- JS_FS_END
- };
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- js_util_prototype = JS_InitClass(cx,
- global,
- NULL,
- js_util_class,
- js_util_constructor,
- 0,
- properties,
- funcs,
- NULL,
- st_funcs);
-
-
- JSBool found;
- JS_SetPropertyAttributes(cx, global, "APP_UTIL", JSPROP_ENUMERATE|JSPROP_READONLY, &found);
- }
四,定义js类的析构和构造函数 析够函数定义如下:
- void js_utility_finalize(JSFreeOp *op, JSObject *obj)
- {
- CCLOG("js_util_class is free : %p", obj);
- }
构造函数定义如下:
- JSBool js_util_constructor(JSContext *cx, uint32_t argc, jsval *vp)
- {
- if (argc != 0) {
- JS_ReportError(cx, "Wrong number of args: %d, was expecting: %d", argc, 0);
- return JS_FALSE;
- }
-
- JSObject *obj = JS_NewObject(cx, js_util_class, js_util_prototype, NULL);
- UtilHelper *cobj = new UtilHelper();
-
-
- js_proxy_t *p = jsb_new_proxy(cobj, obj);
- JS_AddNamedObjectRoot(cx, &p->obj, "APP_UTIL");
-
-
- JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj));
-
- return JS_TRUE;
- }
五,本地c++相关代码(UtilHelper)的实现
在此简略实现,直接定义在“JsbUtil.cpp”文件中,现在只实现一个功能:设置项目的分辨率解决方案,如下:
- class UtilHelper
- {
- public:
- void setDesignResolutionSize(float width, float height, ResolutionPolicy resolutionPolicy)
- {
- CCEGLView::sharedOpenGLView()->setDesignResolutionSize(width, height, resolutionPolicy);
- }
- };
六,实现绑定函数js_util_set_design_resolution
-
-
-
-
- JSBool js_util_set_design_resolution(JSContext *cx, uint32_t argc, jsval *vp)
- {
- if (argc != 3) {
- JS_ReportError(cx, "Wrong number of argc:%d, was expecting: %d", argc, 3);
- return JS_FALSE;
- }
- JSObject *obj_this = JS_THIS_OBJECT(cx, vp);
- js_proxy_t *proxy = jsb_get_js_proxy(obj_this);
- UtilHelper *cobj = (UtilHelper*)(proxy?proxy->ptr:NULL);
- JSB_PRECONDITION2(cobj, cx, JS_FALSE, "Invalid Native object");
-
- jsval *argv = JS_ARGV(cx, vp);
-
- int width = 0;
- if (JSVAL_IS_INT(argv[0])) {
- jsval_to_int32(cx, argv[0], &width);
- }
-
- int height = 0;
- if (JSVAL_IS_INT(argv[1])) {
- jsval_to_int32(cx, argv[1], &height);
- }
-
- std::string data;
- if(JSVAL_IS_STRING(argv[2])){
- jsval_to_std_string(cx, argv[2], &data);
- }
-
- ResolutionPolicy policy = kResolutionUnKnown;
- if (data == std::string("kResolutionExactFit")) {
- policy = kResolutionExactFit;
- }else if(data == std::string("kResolutionNoBorder")){
- policy = kResolutionNoBorder;
- }else if(data == std::string("kResolutionFixedHeight")){
- policy = kResolutionFixedHeight;
- }else if(data == std::string("kResolutionFixedWidth")){
- policy = kResolutionFixedWidth;
- }else if(data == std::string("kResolutionShowAll")){
- policy = kResolutionShowAll;
- }
-
- cobj->setDesignResolutionSize(width, height, policy);
-
- return JS_TRUE;
- }
七,注册调用 新建test_util.js文件放在Resource/script目录下,添加如下代码:
- require("jsb.js")
-
- var director = cc.Director.getInstance();
- var winSize = director.getWinSize();
- var scene = cc.Scene.create();
- var testSprite = cc.Sprite.create('HelloWorld.png');
- scene.addChild(testSprite);
- testSprite.setPosition(cc.p(winSize.width/2, winSize.height/2));
-
- director.runWithScene(scene);
修改AppDelegate.cpp: 1,添加绑定:sc->addRegisterCallback(register_jsb_util);
2,修改执行的脚本为test_util.js:ScriptingCore::getInstance()->runScript("script/test_util.js");
之后使用480x320的模拟器效果图如下:
![](http://img.blog.csdn.net/20141112190251277?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvVGhlS2luZ29mQw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
切换到分辨率大的模拟器后不能再全屏:
![](http://img.blog.csdn.net/20141112190307517?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvVGhlS2luZ29mQw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
在require("jsb.js")下添加如下代码:
- var util = new APP_UTIL();
- util.setDesignResolution(480, 320, 'kResolutionFixedHeight');
之后运行效果如下:![](http://img.blog.csdn.net/20141112190642329?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvVGhlS2luZ29mQw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
九,添加c++回调脚本的功能
在UtilHelper中添加如下代码:
-
- void CallBackJs()
- {
- JSContext *cx = ScriptingCore::getInstance()->getGlobalContext();
- JSObject *jsobj = JS_NewObject(cx, NULL, NULL, NULL);
-
-
- int attr1Val = 1;
- jsval vp;
- vp = int32_to_jsval(cx, attr1Val);
- JS_SetProperty(cx, jsobj, "myAttr1", &vp);
-
- jsval args = OBJECT_TO_JSVAL(jsobj);
-
-
- ScriptingCore::getInstance()->executeFunctionWithOwner(OBJECT_TO_JSVAL(m_pJsDelegate), "onTestCallJs", 1, &args);
- }
-
- void SetJsDelegate(JSObject *pDelegate) {
- m_pJsDelegate = pDelegate;
- }
-
- private:
- JSObject *m_pJsDelegate;
在方法setDesignResolutionSize调用callBackJs- void setDesignResolutionSize(float width, float height, ResolutionPolicy resolutionPolicy)
- {
- CCEGLView::sharedOpenGLView()->setDesignResolutionSize(width, height, resolutionPolicy);
- CallBackJs();
- }
在js_util_constructor中设置util关联的js类:
- JSBool js_util_constructor(JSContext *cx, uint32_t argc, jsval *vp)
- {
- if (argc != 0) {
- JS_ReportError(cx, "Wrong number of args: %d, was expecting: %d", argc, 0);
- return JS_FALSE;
- }
-
- JSObject *obj = JS_NewObject(cx, js_util_class, js_util_prototype, NULL);
- UtilHelper *cobj = new UtilHelper();
- cobj->SetJsDelegate(obj);
- .....
- }
在test_util.js脚本中实现onTestCallJs:
- var util = new APP_UTIL();
- util.onTestCallJs = function(arg) {
- cc.log('call by c++, arg is = ' + JSON.stringify(arg));
- };
再次运行程序,在xcode的输出窗口可以看到如下log:![](http://img.blog.csdn.net/20141112192738241?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvVGhlS2luZ29mQw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
十,至此,js\C++手动绑定,混合调用示例书写完毕。
相关参考:
JavaScript-C/C++ (SpiderMonkey) 引擎嵌入开发指南(中文向导)
JSAPI_reference