cocos2dx手写js绑定C++

来源:互联网 发布:linux怎么改变用户目录 编辑:程序博客网 时间:2024/05/01 05:35

已有 430 次阅读2014-6-19 16:53 |系统分类:Cocos2d| 手游研发

        这两天连续查阅了js绑定c++的很多文章 , 有手动与自动两种方式 .  
        本来想用自动绑定的 , 但是NDK一直下载不下来.....就给算了 . 
        下面总结一下手动绑定的实现过程 :  
        一共三步 : 1 . 写原始 C++ 类 ( 一般放在自定义类库里 ) 
        2. 用 C++ 逐个写 成员函数对应 的 绑定代码 ( 在自定义类库中建立的manual_binding文件夹里) 
        3. 注册所绑定过的函数( 在AppDelegate.cpp中 添加注册函数 ) 
        4. 写js代码测试效果 
        1 . 原始C++类 : 
        
        //test.h
        #include "cocos2d.h"
        USING_NS_CC;
        class testbang
        {
        public:
         testbang();
         ~testbang();
        
        };
         
        //test.cpp
        #include "test.h"
        
        testbang::testbang()
        {
         CCLog("testmyfirstbinding ctor ");
        }
        testbang::~testbang()
        {
         CCLog("testmyfirstbinding destroy");
        }
         2.对应的绑定函数
         
        
        //  jsb_test.h
        #ifndef TestJavascript_jsb_test_h
        #define TestJavascript_jsb_test_h
        
        #include "jsapi.h"
        #include "jsfriendapi.h"
        
        
        void register_jsb_test(JSContext* cx, JSObject* global);
        
        #endif
        
         
        //jsb_test.cpp
        #include "jsb_test.h"
        #include "ScriptingCore.h"
        #include "test.h"
        
        //USING_NS_CC_EXT;
        
        JSClass  *js_test_class;
        JSObject *js_test_prototype;
        
        JSBool js_test(JSContext *cx, uint32_t argc, jsval *vp)
        {
                if (argc == 0) {
                    // 调用 C++ 构造函数
                    testbang* cobj = new testbang();
                    JSObject *obj = JS_NewObject(cx, js_test_class, js_test_prototype, NULL);
                    JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj));
                    // 构造 js 端对象,将 cobj 实际对象存入
                    js_proxy_t* p = jsb_new_proxy(cobj, obj);
                    JS_AddNamedObjectRoot(cx, &p->obj, "TY_test");
                    return JS_TRUE;
                }
                JS_ReportError(cx, "wrong number of arguments: argc, was expecting %d. argc must be 0 ", argc);
                return JS_TRUE;
        }
        // 虚拟机垃圾回收时的回调函数,第一个参数代表runtime,第二个是被垃圾回收的js对象
        void js_test_finalize(JSFreeOp *fop, JSObject *obj) {
            CCLOG("jsbindings: finalizing JS object %p (TY_TCP)", obj);
        }
        // 入口
        void register_jsb_test(JSContext *cx, JSObject *global) {
        
            js_test_class = (JSClass *)calloc(1, sizeof(JSClass));
            js_test_class->name = "TY_test";
            js_test_class->addProperty = JS_PropertyStub;
            js_test_class->delProperty = JS_PropertyStub;
            js_test_class->getProperty = JS_PropertyStub;
            js_test_class->setProperty = JS_StrictPropertyStub;
            js_test_class->enumerate = JS_EnumerateStub;
            js_test_class->resolve = JS_ResolveStub;
            js_test_class->convert = JS_ConvertStub;
            js_test_class->finalize = js_test_finalize;
            js_test_class->flags = JSCLASS_HAS_RESERVED_SLOTS(2);
            
            // 要注册的属性
            static JSPropertySpec properties[] = {
                // 脚本层自己通过回调来设定当前的连接状态,这里就不设置了
        //        {"curState", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_SHARED, JSOP_WRAPPER(js_tuyoo_TCPSocket_get_curState), NULL},
                {0, 0, 0, 0, 0}
            };
            
            // 实例函数
            static JSFunctionSpec funcs[] = {
        
                JS_FS_END
            };
            
            // 类函数
            static JSFunctionSpec st_funcs[] = {
                JS_FS_END
            };
            
            js_test_prototype = JS_InitClass(
                                                  cx, global,
                                                  NULL,
                                                  js_test_class, // 虚拟机内的JSClass类
                                                  js_test, 0, // 构造函数
                                                  properties,
                                                  funcs,
                                                  NULL, // no static properties
                                                  st_funcs);
            
        //    JSObject* obj = JS_NewObject(cx, NULL, NULL, NULL);
            
            // 这个对应一个js的构造函数,在js中使用 new TY_TCP()的方式来使用这个native的类
        //    JSObject* jsclassObj = JSVAL_TO_OBJECT(anonEvaluate(cx, global, "(function () { return TY_TCP; })()"));
            
            // 注册到全局变量中
            JSBool found;
            JS_SetPropertyAttributes(cx, global, "TY_TCP", JSPROP_ENUMERATE | JSPROP_READONLY, &found);
        }
        
        
         3 . 注册绑定函数
         
        
        //AppDelegate.cpp
        #include "manual_bindings/jsb_test.h"
        //bool AppDelegate::applicationDidFinishLaunching()
        sc->addRegisterCallback(register_jsb_test);
         
          4 . 写js代码测试 
        
        var testobj = new TY_test();
         输出 :testmyfirstbinding ctor
         
         
         
0 0
原创粉丝点击