简单执行JS代码 //简单执行JS代码int ExecScript1(JSContext* cx){// Scope for our various stack objects (JSAutoRequest, RootedObject), so they all go// out of scope before we JS_DestroyContext.// In practice, you would want to exit
//简单执行JS代码 int ExecScript1(JSContext* cx) { // Scope for our various stack objects (JSAutoRequest, RootedObject), so they all go // out of scope before we JS_DestroyContext. // In practice, you would want to exit this any time you're spinning the event loop JSAutoRequest ar(cx); //在当前的上下文环境,用创建的全局对象创建根化的全局对象 JS::RootedObject global(cx, JS_NewGlobalObject(cx, &global_class, nullptr, JS::FireOnNewGlobalHook)); if (!global) return 1; //创建一个RootedValue变量用于接收执行的结果,而这个结果的值是一个要被根化的值 JS::RootedValue rval(cx); { // Scope for JSAutoCompartment //进入新全局对象的隔室,好像干什么坏事总是见不得人,非要躲在包厢里做坏事一样 JSAutoCompartment ac(cx, global); //初始化全局对象和其它js里的常规对象 JS_InitStandardClasses(cx, global); const char *script = "'hello'+'world, it is '+new Date()"; const char *filename = "noname"; int lineno = 1; bool ok = JS_EvaluateScript(cx, global, script, strlen(script), filename, lineno, &rval); if (!ok) return 1; } JSString *str = rval.toString(); printf("%s\n", JS_EncodeString(cx, str)); return 0; }操作JS变量
//操作JS变量 int ExecScript2(JSContext* cx) { // In practice, you would want to exit this any time you're spinning the event loop JSAutoRequest ar(cx); //在当前的上下文环境,用创建的全局对象创建根化的全局对象 JS::RootedObject global(cx, JS_NewGlobalObject(cx, &global_class, nullptr, JS::FireOnNewGlobalHook)); if (!global) return 1; // Scope for JSAutoCompartment //进入新全局对象的隔室,好像干什么坏事总是见不得人,非要躲在包厢里做坏事一样 JSAutoCompartment ac(cx, global); //初始化全局对象和其它js里的常规对象 JS_InitStandardClasses(cx, global); const char* script = "var num=123"; const char *filename = "noname"; int lineno = 1; //执行脚本 bool ok = JS_EvaluateScript(cx, global, script, strlen(script), filename, lineno); //创建一个RootedValue变量用于接收执行的结果,而这个结果的值是一个要被根化的值 JS::RootedValue rval(cx); //获取js里的变量的值,js里的变量被视为属性 JS_GetProperty(cx, global, "num", &rval); //将js里的整形变量转换为c++里的整形 int num = JSVAL_TO_INT(rval); printf("设置前num=%d\n", num); //这里再创建一个根化变量用于设置js里的变量值 JS::RootedValue setVal(cx); setVal.setInt32(99); //设置js里变量的值,你换个属性名试试,那就是添加一个属性,当然下面获取也要变为相应的属性名 JS_SetProperty(cx, global, "num", setVal); //再次调用函数获取js变量的值,看是否改变 JS_GetProperty(cx, global, "num", &rval); num = JSVAL_TO_INT(rval); printf("设置后num=%d\n", num); return 0; }主函数
int main(int argc, char* argv[]) { //初始化JS引擎,一定要有这步,不然其它的操作都是扯淡 JS_Init(); //创建运行时,是不是跟以前的不一样了 JSRuntime *rt = JS_NewRuntime(8L * 1024 * 1024, JS_USE_HELPER_THREADS); if (!rt) return 1; //创建一个JS上下文,与运行时关联起来 JSContext *cx = JS_NewContext(rt, 8192); if (!cx) return 1; ExecScript1(cx); ExecScript2(cx); ExecScript3(cx); ExecScript4(cx); ExecScript5(cx); ExecScript6(cx); //销毁创建的上下文 JS_DestroyContext(cx); //销毁释放运行时 JS_DestroyRuntime(rt); //释放js引擎使用的所有资源 JS_ShutDown(); return 0; }操作JS函数
int add(int a, int b) { return a + b; } //这里就是对add函数的包装形式,并且满足JSNative类型 static bool Js_Add(JSContext *cx, unsigned argc, jsval *vp) { JS::CallArgs args = CallArgsFromVp(argc, vp); int retValue = add(args[0].toInt32(), args[1].toInt32()); args.rval().setInt32(retValue); return true; } //这个函数用于演示如何用spidermonkey引擎来定义js函数 static bool Hello(JSContext *cx, unsigned argc, jsval *vp) { printf("Hello world\n"); JS::CallArgs args = CallArgsFromVp(argc, vp); //设置返回值,这里没有返回值,相当于c++里void的函数,不写也可以的 args.rval().setNull(); return true; } int ExecScript3(JSContext* cx) { // In practice, you would want to exit this any time you're spinning the event loop JSAutoRequest ar(cx); //在当前的上下文环境,用创建的全局对象创建根化的全局对象 JS::RootedObject global(cx, JS_NewGlobalObject(cx, &global_class, nullptr, JS::FireOnNewGlobalHook)); if (!global) return 1; // Scope for JSAutoCompartment //进入新全局对象的隔室,好像干什么坏事总是见不得人,非要躲在包厢里做坏事一样 JSAutoCompartment ac(cx, global); //初始化全局对象和其它js里的常规对象 JS_InitStandardClasses(cx, global); //下面用于演示如何调用js里的函数 const char *script = "function add(a,b) {return a+b};"; const char *filename = "noname"; int lineno = 1; //执行脚本 bool ret = JS_EvaluateScript(cx, global, script, strlen(script), filename, lineno); //用于接收返回值 JS::RootedValue rval(cx); //这是需要传递的参数 JS::AutoValueArray<2> arry(cx); arry[0].setInt32(5); arry[1].setInt32(6); //通过函数名调用 JS_CallFunctionName(cx, global, "add", arry, &rval); int num = rval.toInt32(); printf("add函数:num=%d\n", num); //这里用于演示如何从js里调用c++里的函数 JS_DefineFunction(cx, global, "c_add", Js_Add, 2, 0); JS::AutoValueArray<2> argv(cx); argv[0].setInt32(10); argv[1].setInt32(20); JS_CallFunctionName(cx, global, "c_add", argv, &rval); num = rval.toInt32(); printf("c_add函数:num=%d\n", num); //这里用于演示如何从调用spidermonkey定义的函数 JSFunction *pFun = JS_DefineFunction(cx, global, "Hello", Hello, 0, 0);//先定义函数 JS::AutoValueArray<1> argv2(cx); argv2[0].setNull(); JS::RootedFunction rFun(cx, pFun); JS_CallFunction(cx, global, rFun, argv2, &rval);//再调用函数,换一种方法调用 if (rval.isNull()) { printf("Hello函数返回值为null\n"); } return 0; }