js call c++

来源:互联网 发布:西安网络推广公司 编辑:程序博客网 时间:2024/05/16 19:31

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;


void register_jsb(JSContext* cx, JSObject* obj)//注册:全局函数{    jsval nsval;    JSObject* ns;    JS_GetProperty(cx, obj, "TT", &nsval);//c++ 命名空间绑定        if (nsval == JSVAL_VOID)    {        ns = JS_NewObject(cx, NULL, NULL, NULL);        nsval = OBJECT_TO_JSVAL(ns);        JS_SetProperty(cx, obj, "TT", &nsval);//命名空间绑定    }else    {        JS_ValueToObject(cx, nsval, &ns);    }        obj = ns;        js_register(cx, obj);               //调用:绑定类的方法            //JS_DefineFunction:调用全局方法    JS_DefineFunction(cx, jsb_prototype, "retain", JSB_cocos2dx_retain, 0, JSPROP_READONLY | JSPROP_PERMANENT);    JS_DefineFunction(cx, jsb_prototype, "release", JSB_cocos2dx_release, 0, JSPROP_READONLY | JSPROP_PERMANENT);}

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


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

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

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

testJSB.retain();

testJSB.release();

//retain时候调用JSBool JSB_cocos2dx_retain(JSContext* cx, uint32_t argc, jsval *vp){    CCLog("JSB_cocos2dx_retain   ----------  JSB_cocos2dx_retain");        JSObject* thisObj = JS_THIS_OBJECT(cx, vp);        if (thisObj)    {        js_proxy_t* proxy = jsb_get_js_proxy(thisObj);//2dx                if (proxy)        {            ((CCObject* )proxy->ptr)->retain();            CCLog("Retain succeed!");            return JS_TRUE;        }    }        JS_ReportError(cx, "Invaild native object");    return JS_FALSE;}//释放内存调用JSBool JSB_cocos2dx_release(JSContext* cx, uint32_t argc, jsval *vp){    CCLog("JSB_cocos2dx_release   ----------  JSB_cocos2dx_release");        JSObject* thisObj = JS_THIS_OBJECT(cx, vp);        if (thisObj)    {        js_proxy_t* proxy = jsb_get_js_proxy(thisObj);                if (proxy)        {            ((CCObject* )proxy->ptr)->release();            CCLog("Release succeed!");            return JS_TRUE;        }    }        JS_ReportError(cx, "Invaild native object");    return JS_FALSE;}


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

//注册 一些可能被调用的函数void js_register(JSContext* cx, JSObject* global){    CCLog("js_register   ----------  js_register");        jsb_class = (JSClass *)calloc(1, sizeof(JSClass));    jsb_class->name = "test";//类名        jsb_class->addProperty = JS_PropertyStub;    jsb_class->delProperty = JS_PropertyStub;    jsb_class->getProperty = JS_PropertyStub;    jsb_class->setProperty = JS_StrictPropertyStub;    jsb_class->enumerate = JS_EnumerateStub;    jsb_class->resolve = JS_ResolveStub;    jsb_class->convert = JS_ConvertStub;    jsb_class->finalize = js_finalize;//类型析构函数绑定    jsb_class->flags = JSCLASS_HAS_RESERVED_SLOTS(2);        /*     等呆研究     */    static JSPropertySpec properties[] =    {        {0, 0, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER}    };            /*     js 调用 functionTest 方法触发 js_functionTest     */    static JSFunctionSpec funcs[] =    {        JS_FN("functionTest", js_functionTest, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),        JS_FS_END    };            /*     js 调用 create 方法触发 js_create     */    static JSFunctionSpec st_funcs[] =    {        JS_FN("create", js_create, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),        JS_FS_END    };            /*     JS_InitClass:调用对象方法     1:js_constructor 创建类对象注册到 js     2:funcs 注册 js 调用的对象方法     3:st_funcs 注册 js 调用的静态方法     4:properties (可能是注册属性  猜测)     */    jsb_prototype = JS_InitClass(cx, global, NULL, jsb_class, js_constructor, 0, properties, funcs, NULL, st_funcs);    JSBool found;            JS_SetPropertyAttributes(cx, global, "TT", JSPROP_ENUMERATE | JSPROP_READONLY, &found);//命名空间    TypeTest<TT::test> t;//对象            js_type_class_t* p;    uint32_t typeId = t.s_id();//次类对象的唯一标示符    HASH_FIND_INT(_js_global_type_ht, &typeId, p);            if (!p)//绑定对象和方法到 js 上    {        p = (js_type_class_t* )malloc(sizeof(_js_global_type_ht));        p->type = typeId;        p->jsclass = jsb_class;        p->proto = jsb_prototype;        p->parentProto = NULL;        HASH_ADD_INT(_js_global_type_ht, type, p);    }}


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_class,js_constructor, 0, 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++ 对象

 //new创建类对象,并绑定到jsJSBool js_constructor(JSContext* cx, uint32_t argc, jsval* vp){    cocos2d::CCLog("JS Constructor...");    if (argc == 0)    {        TT::test* cobj = new TT::test();//创建注册到 js中 类的对象        cocos2d::CCObject* ccobj = dynamic_cast<cocos2d::CCObject*>(cobj);        if (ccobj) ccobj->autorelease();//2dx 创建对象以后就直接 autorelease                        TypeTest<TT::test> t;                js_type_class_t* typeClass;        uint32_t typeId = t.s_id();        HASH_FIND_INT(_js_global_type_ht, &typeId, typeClass);        assert(typeClass);        JSObject* obj = JS_NewObject(cx, typeClass->jsclass, typeClass->proto, typeClass->parentProto);        JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj));                js_proxy_t* p = jsb_new_proxy(cobj, obj);//2dx                JS_AddNamedObjectRoot(cx, &p->obj, "TT::test");//                        return JS_TRUE;    }        JS_ReportError(cx, "Wrong number of arguments: %d, was expecting: %d", argc, 0);        return JS_FALSE;}//create创建对象时候调用JSBool js_create(JSContext* cx, uint32_t argc, jsval* vp){    cocos2d::CCLog("js is creating...");    if (argc == 0)    {        TT::test* ret = TT::test::create();                jsval jsret;        do        {            if (ret)            {                js_proxy_t* proxy = js_get_or_create_proxy<TT::test>(cx, ret);                                jsret = OBJECT_TO_JSVAL(proxy->obj);            }else            {                jsret = JSVAL_NULL;            }        } while(0);        JS_SET_RVAL(cx, vp, jsret);                return JS_FALSE;    }        JS_ReportError(cx, "Wrong number of arguments");        return JS_FALSE;}


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

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

var testJSB = new TT.test();

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

//调用JSBinding 里的 functionTest 方法JSBool js_functionTest(JSContext* cx, uint32_t argc, jsval* vp){    CCLog("js_functionTest   ---   js_functionTest");        JSBool ok = JS_TRUE;    JSObject* obj = NULL;    TT::test* cobj = NULL;            obj = JS_THIS_OBJECT(cx, vp);    js_proxy_t* proxy = jsb_get_js_proxy(obj);//2dx    cobj = (TT::test* )(proxy ? proxy->ptr : NULL);//通过代理得到自己创建的那个类的对象            JSB_PRECONDITION2(cobj, cx, JS_FALSE, "Invalid Native Object");            if (argc == 0)    {        cobj->functionTest();//调用 TT::test 类对象方法        JS_SET_RVAL(cx, vp, JSVAL_VOID);        return ok;    }        JS_ReportError(cx, "Wrong number of arguments");    return JS_FALSE;}

8.自己的 c++类

test.h

#ifndef __myJSB__test__#define __myJSB__test__#include <iostream>#include "cocos2d.h"#include "ScriptingCore.h"namespace TT{        class test: public cocos2d::CCObject    {    public:        static cocos2d::CCScene* scene();                test();        ~test();                virtual bool init();        CREATE_FUNC(test);        void functionTest();            };}#endif

test.cpp

#include "test.h"bool TT::test::init(){    bool bRef = false;    do    {        cocos2d::CCLog("TT::test init...");        bRef = true;    } while (0);            return bRef;}void TT::test::functionTest(){    cocos2d::CCLog("TT::test test...");}TT::test::test(){}TT::test::~test()// js执行对象 release方法时候调用{    CCLog("~test");}



































0 0
原创粉丝点击