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, ¶msZero);//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);