cocos2dx手写js绑定C++

这两天连续查阅了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


posted @ 2016-01-14 21:39  phlsheji  阅读(1237)  评论(0编辑  收藏  举报