VC驿站

 找回密码
 加入驿站

QQ登录

只需一步,快速开始

搜索
查看: 1967|回复: 0

[分享] SpiderMonkey_31.2.0版编程笔记 三___函数操作一

[复制链接]
04_avatar_middle
online_vip 发表于 2015-9-15 21:24:35 | 显示全部楼层 |阅读模式
本帖最后由 liehuo 于 2015-9-15 22:25 编辑

spidermonkey引擎调用js里的函数用的函数是JS_CallFunction。函数原型如下:
bool JS_CallFunction(JSContext *cx, JS::HandleObject obj, JS::HandleFunction fun, const JS::HandleValueArray& args, JS::MutableHandleValue rval);
还有一种是通过函数名字调用的api函数,原型如下:
bool JS_CallFunctionName(JSContext *cx, JS::HandleObject obj, const char *name,const JS::HandleValueArray& args, JS::MutableHandleValue rval);
我们将通过这两种方法分别调用js函数展现其用法。当然在你调用函数之前应该定义了这个函数,如果没有那就定义一个吧,定义函数的api是JS_DefineFunction:
JSFunction* JS_DefineFunction(JSContext *cx, JS::Handle<JSObject*> obj, const char *name, JSNative call, unsigned nargs, unsigned attrs);
这个函数一次定义一个js函数,如果你觉得麻烦可以使用JS_DefineFunctions这个api。这次就不用这个函数了,因为我不想把代码写的太长,简单一点比较好。下个帖子再用它吧!这个函数里面的参数重要的就是JSNative call这个参数,要求类型是JSNative类型,JSNative是一个函数指针,其原型是:
bool (* JSNative)(JSContext *cx, unsigned argc, JS::Value *vp);
所以只要满足这个条件就可以当作回调函数使用。下面是代码:
  1. #include "stdafx.h"
  2. #include "include/jsapi.h"
  3. #pragma comment(lib,"lib/mozjs-31.lib")//这里直接用这种方式,是为了观看方便
  4. using namespace JS;
  5. static JSClass global_class = {
  6.         "global",
  7.         JSCLASS_GLOBAL_FLAGS,
  8.         JS_PropertyStub,          //增加属性
  9.         JS_DeletePropertyStub,    //删除属性
  10.         JS_PropertyStub,          //获取属性
  11.         JS_StrictPropertyStub,    //设置属性
  12.         JS_EnumerateStub,
  13.         JS_ResolveStub,
  14.         JS_ConvertStub
  15. };
  16. int add(int a, int b){ return a + b; }//这个函数是c++里面的函数,不是js里的函数,要想从js里调用c++里面的函数就要为其包装,包装成js可以识别的函数
  17. static bool Js_Add(JSContext *cx, unsigned argc, jsval *vp)//这里就是对add函数的包装形式,并且满足JSNative类型
  18. {
  19.         JS::CallArgs args = CallArgsFromVp(argc, vp);
  20.         int retValue = add(args[0].toInt32(), args[1].toInt32());
  21.         args.rval().setInt32(retValue);
  22.         return true;
  23. }
  24. static bool Hello(JSContext *cx, unsigned argc, jsval *vp)//这个函数用于演示如何用spidermonkey引擎来定义js函数
  25. {
  26.         printf("Hello world\n");
  27.         JS::CallArgs args = CallArgsFromVp(argc, vp);
  28.         args.rval().setNull();         //设置返回值,这里没有返回值,相当于c++里void的函数,不写也可以的
  29.         return true;
  30. }
  31. void ExecScript(JSContext *cx)
  32. {
  33.         JSObject *obj = JS_NewGlobalObject(cx, &global_class, nullptr, FireOnNewGlobalHook);//创建一个新的JS对象用作一个全局对象,但是要被根化这里没有被根化。
  34.         //RootedObject global(cx, JS_NewGlobalObject(cx, &global_class, nullptr, FireOnNewGlobalHook));//上面和下面的可以并作中间的这一句。分开写是为了循序渐进
  35.         RootedObject global(cx, obj);//在当前的上下文环境,用创建的全局对象创建根化的全局对象
  36.         JSAutoCompartment ac(cx, global);//进入新全局对象的隔室,好像干什么坏事总是见不得人,非要躲在包厢里做坏事一样
  37.         JS_InitStandardClasses(cx, global);//初始化全局对象和其它js里的常规对象

  38.         //下面用于演示如何调用js里的函数
  39.         const char *script = "function add(a,b){return a+b};";
  40.         const char *filename = "noname";
  41.         int lineno = 1;
  42.         bool ret = JS_EvaluateScript(cx, global, script, strlen(script), filename, lineno);

  43.         RootedValue rval(cx);//用于接收返回值
  44.         AutoValueArray<2> arry(cx);//这是需要传递的参数
  45.         arry[0].setInt32(5);
  46.         arry[1].setInt32(6);
  47.         JS_CallFunctionName(cx, global, "add", arry, &rval);//通过函数名调用
  48.         int num = rval.toInt32();
  49.         printf("add函数:num=%d\n", num);

  50.         //这里用于演示如何从js里调用c++里的函数
  51.         JS_DefineFunction(cx, global, "c_add", Js_Add, 2, 0);
  52.         JS::AutoValueArray<2> argv(cx);
  53.         argv[0].setInt32(10);
  54.         argv[1].setInt32(20);
  55.         JS_CallFunctionName(cx, global, "c_add", argv, &rval);
  56.         num = rval.toInt32();
  57.         printf("c_add函数:num=%d\n", num);

  58.         //这里用于演示如何从调用spidermonkey定义的函数
  59.         JSFunction *pFun= JS_DefineFunction(cx, global, "Hello", Hello, 0, 0);//先定义函数
  60.         JS::AutoValueArray<1> argv2(cx);
  61.         argv2[0].setNull();
  62.         RootedFunction rFun(cx, pFun);
  63.         JS_CallFunction(cx,global, rFun, argv2, &rval);//再调用函数,换一种方法调用
  64.         if (rval.isNull())
  65.         {
  66.                 printf("Hello函数返回值为null\n");
  67.                 printf("\n");
  68.                 return;
  69.         }
  70. }
  71. int _tmain(int argc, _TCHAR* argv[])
  72. {
  73.         JS_Init();     //初始化JS引擎,一定要有这步,不然其它的操作都是扯淡
  74.         JSRuntime *rt = JS_NewRuntime(8L * 1024 * 1024, JS_USE_HELPER_THREADS);//创建运行时,是不是跟以前的不一样了
  75.         if (!rt)
  76.                 return 1;
  77.         JSContext *cx = JS_NewContext(rt, 8192);//创建一个JS上下文,与运行时关联起来
  78.         if (!cx)
  79.                 return 1;
  80.         //****************************************************************************************
  81.             ExecScript(cx);
  82.         //****************************************************************************************
  83.         JS_DestroyContext(cx);//销毁创建的上下文
  84.         JS_DestroyRuntime(rt);//销毁释放运行时
  85.         JS_ShutDown();        //释放js引擎使用的所有资源
  86.         return 0;
  87. }
复制代码

运行结果:
SpiderMonkey_31.2.0版编程笔记 三___函数操作一

上一篇:SpiderMonkey_31.2.0版编程笔记 二___变量操作
下一篇:SpiderMonkey_31.2.0版编程笔记 四___函数操作二






上一篇:SpiderMonkey_31.2.0版编程笔记 二___变量操作
下一篇:SpiderMonkey_31.2.0版编程笔记 四___函数操作二
您需要登录后才可以回帖 登录 | 加入驿站 qq_login

本版积分规则

关闭

站长提醒上一条 /2 下一条

QQ|小黑屋|手机版|VC驿站 ( 辽ICP备09019393号tongdun|网站地图wx_jqr

GMT+8, 2019-3-23 22:05

Powered by Discuz! X3.4

© 2009-2019 cctry.com

快速回复 返回顶部 返回列表