下面总结一下手动绑定的实现过程 :
一共三步 :
绑定所需的spidermonkey目录如上
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