Cocos中Js和cpp通信

2017-10-11  本文已影响79人  VegetableAD

得到引擎的实力单例对象后调用addRegisterCallback去注册方法

#ifndef jsb_jsb_kenko_auto_h 
#define jsb_jsb_kenko_auto_h

#include "scripting/js-bindings/manual/cocos2d_specifics.hpp"
#include "cocos2d.h"

#define JS_SET_RVAL(cx,vp,v)    (*(vp) = (v))

std::string os_info();

bool jsb_os_info(JSContext *cx, uint32_t argc, JS::Value *vp);

void register_jsb_kenko_all(JSContext* cx, JS::HandleObject obj);

bool callJsFunc(JSContext* cx, JS::RootedValue *rv);

#endif
#include "My_Test_Jsb.h"

std::string os_info(std::string str) {

    CCLOG("it's c++ os_info here aaa %s",str.c_str());

    return "";

}

//参数格式是固定的,第二个参数是调用者提供的,而不是JS_DefineFunction设置的值
//被调用者的Function对象可以通过这个指针使用下面描述的宏来访问。
bool jsb_os_info(JSContext *cx, uint32_t argc, JS::Value *vp) {

    //JS::CallArgsFromVp为被调用函数的封装,封装了值,参数,参数个数
    JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
    //JS::CallArgs中封装的方法查看https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_reference/JS::CallArgs
    bool ok = true;
    std::string paramsZero;

    CCLOG("the argc number is %d",args.length());


    if (args.length() > 0 && args.hasDefined(0)){
        JS::HandleValue hv = args.get(0);
        if (hv.isString()){
            ok &= jsval_to_std_string(cx, hv, &paramsZero);//JS中的字符串由0到多个16位的unicode字符组成
        }
    }

    CCLOG("the params is %s", paramsZero.c_str());

    //判断参数存在并且转换成功
    if (!ok){
        ok = true; 
        return false;
    }
    args.rval();

    jsval ret = std_string_to_jsval(cx, os_info(paramsZero));//这里是设置返回值

    //成功的话,必须使用JS::CallArgs::rval() 或者 JS_SET_RVAL返回true,否则会报告错误
    JS_SET_RVAL(cx, vp, ret);

    return true;

}

void register_jsb_kenko_all(JSContext* cx, JS::HandleObject obj) {
    //第二个参数是为哪个对象定义函数作为属性,引用一个已经扎根于其他地方的T。 这是一个最有用的参数类型,它可以保证T值正确扎根。
    //详细看https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_reference/JS::Handle
    //第四个参数是当调用函数的时候传递的参数个数,
    //第五个参数是JS对象的属性集(任何对象都可以有0个或多个属性集,下例中JSPROP_PERMANENT表示属性不可被删除)
    JS_DefineFunction(cx, obj, "osInfo", jsb_os_info, 1, JSPROP_READONLY | JSPROP_PERMANENT);  //生成名为osInfo的js全局函数
}

bool callJsFunc(JSContext* cx, JS::RootedValue* rv){
    int State = 50;
    char* buf = new char[64];
    sprintf(buf, "prepareForCpp(%d)", State);
    //jsval
    JS::MutableHandleValue handle(rv);//和handle相似,只是它保存的值可以改变

    return ScriptingCore::getInstance()->evalString(buf, handle);
}

引擎启动之后调用

    //以下代码为读取js返回的值
    JSContext *cx = ScriptingCore::getInstance()->getGlobalContext();
    JS::RootedValue rv(cx);
    callJsFunc(cx,&rv);
    if (rv.isObject()){
        CCLOG("object");
    }
    else if (rv.isPrimitive()){
        CCLOG("primitive");
    }
    int back = rv.toInt32();
    CCLOG("the value is %d",back);
上一篇下一篇

猜你喜欢

热点阅读