js call c++

0.声明

TT命名空间  类名test

1.创建一个 2dx 的 js 项目。

2.新创建一个 jsbRegister.cpp 文件,jsbRegister.h文件中声明一个全局方法。   

#include <iostream>

#include "jsapi.h"

#include "jsfriendapi.h"

#include "ScriptingCore.h"


#include "test.h"


void register_jsb(JSContext* cx,JSObject* obj);

3. 2dx 的 AppDelegate.cpp 中引进头文件,jsbRegister.h

  ScriptingCore* sc = ScriptingCore::getInstance();

  sc->addRegisterCallback(register_jsb);

  sc->start();

4. jsbRegister.cpp 去实现这个方法

#include "jsbRegister.h"

#include "cocos2d.h"

#include "cocos2d_specifics.hpp"


JSClass*        jsb_class;//全局变量

JSObject*       jsb_prototype;


[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. void register_jsb(JSContext* cx, JSObject* obj)//注册:全局函数  
  2. {  
  3.     jsval nsval;  
  4.     JSObject* ns;  
  5.     JS_GetProperty(cx, obj, "TT", &nsval);//c++ 命名空间绑定  
  6.       
  7.     if (nsval == JSVAL_VOID)  
  8.     {  
  9.         ns = JS_NewObject(cx, NULL, NULL, NULL);  
  10.         nsval = OBJECT_TO_JSVAL(ns);  
  11.         JS_SetProperty(cx, obj, "TT", &nsval);//命名空间绑定  
  12.     }else  
  13.     {  
  14.         JS_ValueToObject(cx, nsval, &ns);  
  15.     }  
  16.       
  17.     obj = ns;  
  18.       
  19.     js_register(cx, obj);               //调用:绑定类的方法  
  20.       
  21.       
  22.     //JS_DefineFunction:调用全局方法  
  23.     JS_DefineFunction(cx, jsb_prototype, "retain", JSB_cocos2dx_retain, 0, JSPROP_READONLY | JSPROP_PERMANENT);  
  24.     JS_DefineFunction(cx, jsb_prototype, "release", JSB_cocos2dx_release, 0, JSPROP_READONLY | JSPROP_PERMANENT);  
  25. }  

js_register(cx, obj);  全局方法,创建 c++ 类的对象。


JS_DefineFunction(cx, jsb_prototype,"retain"JSB_cocos2dx_retain,0JSPROP_READONLY |JSPROP_PERMANENT);

通过 js 对象调用 retain 方法可以执行 c++ 全局方法 JSB_cocos2dx_retain

var testJSB = new TT.test();//创建 js 绑定的 c++对象

testJSB.retain();

testJSB.release();

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. //retain时候调用  
  2. JSBool JSB_cocos2dx_retain(JSContext* cx, uint32_t argc, jsval *vp)  
  3. {  
  4.     CCLog("JSB_cocos2dx_retain   ----------  JSB_cocos2dx_retain");  
  5.       
  6.     JSObject* thisObj = JS_THIS_OBJECT(cx, vp);  
  7.       
  8.     if (thisObj)  
  9.     {  
  10.         js_proxy_t* proxy = jsb_get_js_proxy(thisObj);//2dx  
  11.           
  12.         if (proxy)  
  13.         {  
  14.             ((CCObject* )proxy->ptr)->retain();  
  15.             CCLog("Retain succeed!");  
  16.             return JS_TRUE;  
  17.         }  
  18.     }  
  19.       
  20.     JS_ReportError(cx, "Invaild native object");  
  21.     return JS_FALSE;  
  22. }  
  23.   
  24.   
  25. //释放内存调用  
  26. JSBool JSB_cocos2dx_release(JSContext* cx, uint32_t argc, jsval *vp)  
  27. {  
  28.     CCLog("JSB_cocos2dx_release   ----------  JSB_cocos2dx_release");  
  29.       
  30.     JSObject* thisObj = JS_THIS_OBJECT(cx, vp);  
  31.       
  32.     if (thisObj)  
  33.     {  
  34.         js_proxy_t* proxy = jsb_get_js_proxy(thisObj);  
  35.           
  36.         if (proxy)  
  37.         {  
  38.             ((CCObject* )proxy->ptr)->release();  
  39.             CCLog("Release succeed!");  
  40.             return JS_TRUE;  
  41.         }  
  42.     }  
  43.       
  44.     JS_ReportError(cx, "Invaild native object");  
  45.     return JS_FALSE;  
  46. }  


5.jsbRegister.cpp  js绑定c++对象方法

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. //注册 一些可能被调用的函数  
  2. void js_register(JSContext* cx, JSObject* global)  
  3. {  
  4.     CCLog("js_register   ----------  js_register");  
  5.       
  6.     jsb_class = (JSClass *)calloc(1, sizeof(JSClass));  
  7.     jsb_class->name = "test";//类名  
  8.       
  9.     jsb_class->addProperty = JS_PropertyStub;  
  10.     jsb_class->delProperty = JS_PropertyStub;  
  11.     jsb_class->getProperty = JS_PropertyStub;  
  12.     jsb_class->setProperty = JS_StrictPropertyStub;  
  13.     jsb_class->enumerate = JS_EnumerateStub;  
  14.     jsb_class->resolve = JS_ResolveStub;  
  15.     jsb_class->convert = JS_ConvertStub;  
  16.     jsb_class->finalize = js_finalize;//类型析构函数绑定  
  17.     jsb_class->flags = JSCLASS_HAS_RESERVED_SLOTS(2);  
  18.       
  19.     /* 
  20.      等呆研究 
  21.      */  
  22.     static JSPropertySpec properties[] =  
  23.     {  
  24.         {0, 0, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER}  
  25.     };  
  26.       
  27.       
  28.     /* 
  29.      js 调用 functionTest 方法触发 js_functionTest 
  30.      */  
  31.     static JSFunctionSpec funcs[] =  
  32.     {  
  33.         JS_FN("functionTest", js_functionTest, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),  
  34.         JS_FS_END  
  35.     };  
  36.       
  37.       
  38.     /* 
  39.      js 调用 create 方法触发 js_create 
  40.      */  
  41.     static JSFunctionSpec st_funcs[] =  
  42.     {  
  43.         JS_FN("create", js_create, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),  
  44.         JS_FS_END  
  45.     };  
  46.       
  47.       
  48.     /* 
  49.      JS_InitClass:调用对象方法 
  50.      1:js_constructor 创建类对象注册到 js 
  51.      2:funcs 注册 js 调用的对象方法 
  52.      3:st_funcs 注册 js 调用的静态方法 
  53.      4:properties (可能是注册属性  猜测) 
  54.      */  
  55.     jsb_prototype = JS_InitClass(cx, global, NULL, jsb_class, js_constructor, 0, properties, funcs, NULL, st_funcs);  
  56.     JSBool found;  
  57.       
  58.       
  59.     JS_SetPropertyAttributes(cx, global, "TT", JSPROP_ENUMERATE | JSPROP_READONLY, &found);//命名空间  
  60.     TypeTest<TT::test> t;//对象  
  61.       
  62.       
  63.     js_type_class_t* p;  
  64.     uint32_t typeId = t.s_id();//次类对象的唯一标示符  
  65.     HASH_FIND_INT(_js_global_type_ht, &typeId, p);  
  66.       
  67.       
  68.     if (!p)//绑定对象和方法到 js 上  
  69.     {  
  70.         p = (js_type_class_t* )malloc(sizeof(_js_global_type_ht));  
  71.         p->type = typeId;  
  72.         p->jsclass = jsb_class;  
  73.         p->proto = jsb_prototype;  
  74.         p->parentProto = NULL;  
  75.         HASH_ADD_INT(_js_global_type_ht, type, p);  
  76.     }  
  77. }  


void js_finalize(JSFreeOp* fop,JSObject* obj)//一直没有被成功调用过 ???

{

    CCLog("js_finalize   ----------  js_finalize");

    CCLOGINFO("JSBindings: finallizing JS object %p JSB", obj);

}

 

JS_InitClass(cx, global, NULL,jsb_classjs_constructor0, properties, funcs, NULL, st_funcs);

var testJSB = new TT.test();  new 时候调用 js_constructor 全局方法


var testJSB = TT.test.create(); 调用 js_create

testJSB.functionTest();调用  js_functionTest


6.jsbRegister 两张在 js绑定中创建 c++ 对象

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1.    
  2. //new创建类对象,并绑定到js  
  3. JSBool js_constructor(JSContext* cx, uint32_t argc, jsval* vp)  
  4. {  
  5.     cocos2d::CCLog("JS Constructor...");  
  6.     if (argc == 0)  
  7.     {  
  8.         TT::test* cobj = new TT::test();//创建注册到 js中 类的对象  
  9.         cocos2d::CCObject* ccobj = dynamic_cast<cocos2d::CCObject*>(cobj);  
  10.         if (ccobj) ccobj->autorelease();//2dx 创建对象以后就直接 autorelease  
  11.           
  12.           
  13.         TypeTest<TT::test> t;  
  14.           
  15.         js_type_class_t* typeClass;  
  16.         uint32_t typeId = t.s_id();  
  17.         HASH_FIND_INT(_js_global_type_ht, &typeId, typeClass);  
  18.         assert(typeClass);  
  19.         JSObject* obj = JS_NewObject(cx, typeClass->jsclass, typeClass->proto, typeClass->parentProto);  
  20.         JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj));  
  21.           
  22.   
  23.         js_proxy_t* p = jsb_new_proxy(cobj, obj);//2dx  
  24.           
  25.         JS_AddNamedObjectRoot(cx, &p->obj, "TT::test");//  
  26.           
  27.           
  28.         return JS_TRUE;  
  29.     }  
  30.       
  31.     JS_ReportError(cx, "Wrong number of arguments: %d, was expecting: %d", argc, 0);  
  32.       
  33.     return JS_FALSE;  
  34. }  
  35.   
  36. //create创建对象时候调用  
  37. JSBool js_create(JSContext* cx, uint32_t argc, jsval* vp)  
  38. {  
  39.     cocos2d::CCLog("js is creating...");  
  40.     if (argc == 0)  
  41.     {  
  42.         TT::test* ret = TT::test::create();  
  43.           
  44.         jsval jsret;  
  45.         do  
  46.         {  
  47.             if (ret)  
  48.             {  
  49.                 js_proxy_t* proxy = js_get_or_create_proxy<TT::test>(cx, ret);  
  50.                   
  51.                 jsret = OBJECT_TO_JSVAL(proxy->obj);  
  52.             }else  
  53.             {  
  54.                 jsret = JSVAL_NULL;  
  55.             }  
  56.         } while(0);  
  57.         JS_SET_RVAL(cx, vp, jsret);  
  58.           
  59.         return JS_FALSE;  
  60.     }  
  61.       
  62.     JS_ReportError(cx, "Wrong number of arguments");  
  63.       
  64.     return JS_FALSE;  
  65. }  


7. js 通过 jsb 调用 c++的对象方法

通过前面的注册,可以用 js 去调用 c++ 的全局方法,js_functionTest 在前面  js_register 被注册过了。

var testJSB = new TT.test();

testJSB.functionTest(); 先调用 jsb方法 functionTest 在通过前面的注册调用c++方法

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. //调用JSBinding 里的 functionTest 方法  
  2. JSBool js_functionTest(JSContext* cx, uint32_t argc, jsval* vp)  
  3. {  
  4.     CCLog("js_functionTest   ---   js_functionTest");  
  5.       
  6.     JSBool ok = JS_TRUE;  
  7.     JSObject* obj = NULL;  
  8.     TT::test* cobj = NULL;  
  9.       
  10.       
  11.     obj = JS_THIS_OBJECT(cx, vp);  
  12.     js_proxy_t* proxy = jsb_get_js_proxy(obj);//2dx  
  13.   
  14.     cobj = (TT::test* )(proxy ? proxy->ptr : NULL);//通过代理得到自己创建的那个类的对象  
  15.       
  16.       
  17.     JSB_PRECONDITION2(cobj, cx, JS_FALSE, "Invalid Native Object");  
  18.       
  19.       
  20.     if (argc == 0)  
  21.     {  
  22.         cobj->functionTest();//调用 TT::test 类对象方法  
  23.         JS_SET_RVAL(cx, vp, JSVAL_VOID);  
  24.         return ok;  
  25.     }  
  26.       
  27.     JS_ReportError(cx, "Wrong number of arguments");  
  28.     return JS_FALSE;  
  29. }  

8.自己的 c++类

test.h

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #ifndef __myJSB__test__  
  2. #define __myJSB__test__  
  3.   
  4. #include <iostream>  
  5. #include "cocos2d.h"  
  6. #include "ScriptingCore.h"  
  7.   
  8. namespace TT  
  9. {  
  10.       
  11.     class test: public cocos2d::CCObject  
  12.     {  
  13.     public:  
  14.         static cocos2d::CCScene* scene();  
  15.           
  16.         test();  
  17.         ~test();  
  18.           
  19.         virtual bool init();  
  20.         CREATE_FUNC(test);  
  21.         void functionTest();  
  22.           
  23.     };  
  24. }  
  25.   
  26.   
  27.   
  28. #endif  

test.cpp

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #include "test.h"  
  2.   
  3.   
  4. bool TT::test::init()  
  5. {  
  6.     bool bRef = false;  
  7.     do  
  8.     {  
  9.         cocos2d::CCLog("TT::test init...");  
  10.         bRef = true;  
  11.     } while (0);  
  12.       
  13.       
  14.     return bRef;  
  15. }  
  16.   
  17.   
  18. void TT::test::functionTest()  
  19. {  
  20.     cocos2d::CCLog("TT::test test...");  
  21.   
  22. }  
  23.   
  24. TT::test::test(){}  
  25. TT::test::~test()// js执行对象 release方法时候调用  
  26. {  
  27.     CCLog("~test");  
  28.   
  29. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值