简单执行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;
}
