在SpiderMonkey里,JS的变量、函数、类等,都被视作global object的特性,因此,如果你的JavaScript如下面这样: /*JavaScript*/ var a = 12; var b = 25; var num = a + b; 那么,如果在C/C++应用程序中要找出num等于多少,该怎么寻找呢? 这时,我们应该知道,当SpiderMonkey解释了上面的JavaScript语句后,其中的变量a、b和num都是某个global object的特性。找到这个object,再利用JSAPI的 bool JS_GetProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::MutableHandleValue vp); 这个函数,就可以提取特性值。这个JSAPI的返回值是bool,参数有:cx(上下文),obj(就是object,下面需要寻找的),name(特性的名称,这里就是我们要找的num),vp(就是特性的数值,也就是我们想要知道的num的值)。 因此,只要找到这个object,则要利用上面的JSAPI,就可得到num。要找到那个obj,就可以使用下面这个JSAPI。 JSObject* CurrentGlobalOrNull(JSContext* cx); 从上面的代码可以看出,这个JSAPI返回一个JSObject*,而参数只有JSContext* cx。下面就是怎么得到num值的C++代码。(这些代码只要添加到前面笔记2中的ExecuteCodePrintResult方法内JS已经编译后的语句下面(也就是提取已经编译后的结果),同时修改 HelloExample中的ExecuteCodePrintResult(cx, R"js(`hello world, it is ${new Date()}`)js");中的内容为:ExecuteCodePrintResult(cx, R"js( var a = 12; var b = 25; var num = a + b; )js"); 即可,日志中不好贴代码,就不贴全部的代码了) //找到obj JS::RootedObject obj(cx, JS::CurrentGlobalOrNull(cx)); //定义一个“根化”的JS::Value,用来存放num的值,也就是上个JSAPI中的vp JS::RootedValue rval(cx); //取得特性num的数值 JS_GetProperty(cx, obj, "num", &rval); //(上面一行JSAPI的返回值是bool,所以上面的代码可以这样来写) //定义一个bool变量ok bool ok; //用ok接收提取特性是否成功 ok = JS_GetProperty(cx, obj, "num", &rval); //根据ok显示结果 if(ok){ //这里的rval.toInt32()就是将JS::Value转换成int printf("The num is %d\n", rval.toInt32()); } else { printf("The num isn't found!\n"); return false; } 程序运行结果会显示: The num is 37 另外,在前面提到的JSAPI手册中有说明:如果在JSNative内,寻找object的方法可以使用下面的JSAPI,原文如下: But in a JSNative the correct way to do this is: /* JSAPI */ bool myNative(JSContext *cx, unsigned argc, JS::Value *vp) { JS::CallArgs args = JS::CallArgsFromVp(argc, vp); JSObject *global = JS_GetGlobalForObject(cx, &args.callee()); ... } 也就是说,在JSNative的内部寻找object,应该使用的JSAPI是: JSObject* JS_GetGlobalForObject(JSContext* cx, JSObject* obj); 上面的JSAPI,等我们学习到JSNative时,再讨论。
|
|
来自: Dark_f > 《JavaScript》