初次使用SpiderMonkey,对它了解并不多,所以它是什么,请自行去搜索。本文只讲述我们用SpiderMonkey能做什么,我们可以用c/c++调用SpiderMonkey的接口,去执行JavaScript代码。这听起来是不是很酷,现在一起开始吧。

安装

我在linux下,安装很简单,去http://ftp.mozilla.org/pub/mozilla.org/js/下载源码包js-1.7.0.tar.gz,解压后在src/下执行make -f Makefile.ref即可,完成后会生成一个新的目录Linux_All_DBG.OBJ,其中包含静态链接库 libjs.a 和动态链接库 libjs.so 等。

详细请访问基于 C 语言的 JavaScript 引擎探索,本文也是参考此文写的,其中大部分代码来自此文。

SpiderMonkey的api这里不赘述,感兴趣的可以访问 SpiderMonkey官方网站。下面直接附上代码。

代码

.
├── fun.js    --JavaScript代码,为求简单,里面只有2个函数
├── lib        --Linux_All_DBG.OBJ目录的拷贝,里面的.o文件已被我删除,剩余2个.h文件,libjs.a,libjs.so
├── m         --本人比较懒,把gcc命令写到了这个文件,当shell执行
├── src        --src目录的拷贝
└── testjs.cc  --源代码

fun.js

function add(x, y) {return x + y;
}function mul(x, y) {return x * y;
}

代码简单到不能在简单。

testjs.cc

定义了一个类JSCaller,将js文件加载封装了起来,只调用一次。js中函数可调用多次。

#include <string>#include "jsapi.h"/* The class of the global object. */
static JSClass global_class = {"global", JSCLASS_GLOBAL_FLAGS,JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,JSCLASS_NO_OPTIONAL_MEMBERS
};class JSCaller {public:JSCaller();~JSCaller();bool Build(const std::string& file);void Run();private:JSBool EvalScriptFromFile(JSContext *context, const char *file);JSRuntime *runtime_;JSContext *context_;JSObject *global_;
};int main() {JSCaller caller;if (!caller.Build("fun.js")) { // 加载js文件,只调用一次return -1;}caller.Run();  // 执行js中的函数,里面执行了多次函数return 0;
}JSCaller::JSCaller() {runtime_ = NULL;context_ = NULL;global_ = NULL;
}JSCaller::~JSCaller() {if (context_ != NULL) {JS_DestroyContext(context_);}if (runtime_ != NULL) {JS_DestroyRuntime(runtime_);}JS_ShutDown();
}/* The error reporter callback. */
void ReportError(JSContext *cx, const char *message, JSErrorReport *report) {if (report->filename == NULL) {fprintf(stderr, "%s\n", message);} else {fprintf(stderr, "%s:%d:%s\n", report->filename, report->lineno, message);}
}bool JSCaller::Build(const std::string& file) {runtime_ = JS_NewRuntime(8L * 1024L * 1024L);if (runtime_ == NULL) {return false;}context_ = JS_NewContext(runtime_, 512 * 1024);if (context_ == NULL) {return false;}JS_SetOptions(context_, JSOPTION_VAROBJFIX);JS_SetErrorReporter(context_, ReportError);global_ = JS_NewObject(context_, &global_class, NULL, NULL);if (global_ == NULL) {return false;}if (!JS_InitStandardClasses(context_, global_)) {return false;}JSBool status = EvalScriptFromFile(context_, file.c_str());if (status == JS_FALSE){fprintf(stderr, "error while evaluate the script\n");return false;}return true;
}JSBool JSCaller::EvalScriptFromFile(JSContext *context, const char *file) {JSScript *script;// JSString *jss;JSBool status;jsval value;//get the global objectJSObject *global = JS_GetGlobalObject(context);//compile the script for further usingscript = JS_CompileFile(context, global, file);if (script == NULL) {return JS_FALSE;}//execute it oncestatus = JS_ExecuteScript(context, global, script, &value);/*jss = JS_ValueToString(context, value);printf("eval script result is : %s\n", JS_GetStringBytes(jss));*///destory the script objectJS_DestroyScript(context, script);return status;
}void JSCaller::Run() {
// 调用1000次add和mul函数
for (int i = 0; i < 1000; ++i) {jsval res;JSObject *global = JS_GetGlobalObject(context_);jsval argv[2];// 构造函数的参数JS_NewNumberValue(context_, i, &res);argv[0] = res;JS_NewNumberValue(context_, i+10, &res);argv[1] = res;const char *p = "add";if (i % 2 == 0) {p = "mul";}
// 调用函数
JS_CallFunctionName(context_, global, p, 2, argv, &res);//convert the result to jsdoublejsdouble d;JS_ValueToNumber(context_, res, &d);printf("%s result = %f\n", p, d);}
}

编译命令

g++ -I./lib -I./src -DXP_UNIX -L./lib -ljs -g -Wall -o jstest testjs.cc

-I./lib,是因为lib/中也有2个.h文件,不然找不到会报很多错。

本打算使用静态库编译,使用-Wl,-Bstatic -ljs -Wl,-Bdynamic后总是报错,最后放弃了。

所以编译出的二进制执行前,别忘了export LD_LIBRARY_PATH=lib/。

初次使用SpiderMonkey相关推荐

  1. celery的初次使用

    celery的初次使用 基本步骤: 选择并且安装一个消息中间件(Broker) 安装 Celery 并且创建第一个任务 运行职程(Worker)以及调用任务 跟踪任务的情况以及返回值 应用 创建第一个 ...

  2. 阿里云服务器ECS Ubuntu16.04 初次使用配置教程(图形界面安装)

    阿里云服务器ECS Ubuntu16.04 初次使用配置教程(图形界面安装) 2019-01-23 22:55:50 laugh12321 阅读数 851更多 分类专栏: ECS Ubuntu 版权声 ...

  3. 人脸识别算法初次了解

    人脸识别算法初次了解 这是转载别人的帖子,认为好,大家一块学习http://www.cnblogs.com/guoyiqi/archive/2011/07/28/2129300.html 前言 在写此 ...

  4. Cash Shuffle初次测试成功,BCH隐私研究逐步推进

    早在去年12月,一项名为 Cash Shuffle的比特币现金项目就被提了出来,该项目旨在通过混淆交易信息来保证BCH交易隐私.该项目在当时引起了社区的热议,因为隐私属性一直是加密货币最重要的属性之一 ...

  5. MySQL的安装和初次使用

    MySQL的安装和初次使用 1.去数据库的官网http://www.mysql.com下载MySQL: 2.找到如下图所示: 下好后按照next/execut安装即可,会有设置密码页: 安装好以后可能 ...

  6. SpiderMonkey-让你的C++程序支持JavaScript脚本

    译序 有些网友对为什么D2JSP能运行JavaScript脚本程序感到奇怪,因此我翻译了这篇文章,原文在这里.这篇教程手把手教你如何利用SpiderMonkey创建一个能执行JavaScript脚本的 ...

  7. 初次安装Magento商城 后台报错的解决方案

    今天初次安装Magento, 开始装的是英文版,后来又找到中文版 安装后在后台都有同一个错误,就是登陆后台,随便点击一个链接,都有报错 There has been an error processi ...

  8. Struts2笔记——初次框架配置

    1.Struts2简介   Struts 2是Struts的下一代产品,是在 struts 1和WebWork的技术基础上进行了合并的全新的Struts 2框架.其全新的Struts 2的体系结构与S ...

  9. git 上传代码到指定仓库_初次使用git上传代码到github远程仓库

    一.新建代码库 注册好github登录后,首先先在网页上新建代码库. 点击右上角"+"→New repository 进入如下页面:按照要求填写完成后,点击按钮创建代码库创建成功. ...

最新文章

  1. C语言 输入中文语句并按倒叙将它输出
  2. java百度地图地名定位地址_百度地图定位显示省市区街道名称,非常实用
  3. Apache 2.4 配置多个虚拟主机的问题
  4. npm 删除依赖包_前端开发,npm会了吗?
  5. 用java正则表达式验证字符串(邮箱与网址)
  6. JavaScript数组sort()方法小结
  7. PREV-55 小计算器 (进制转换)
  8. 4n35光耦引脚图_光耦合器隔离技术在工业环境中的应用!-先进光半导体
  9. 今天写了个查看 ABAP 类层级的程序
  10. Xcode9.0、Xcode9.1修改模拟器尺寸
  11. 怎样使用计算机定时关机,详细教你电脑如何设置定时关机
  12. 【学习笔记】分布式追踪Tracing
  13. 苹果手机信号是哪个服务器,为什么普遍苹果手机信号比安卓机还要差呢?总算是搞明白了...
  14. UMI+TS项目 配置多环境打包
  15. 网络安全专业的就业方向有哪些?
  16. unity游戏入门1
  17. IDC许可证是什么,如何申请IDC许可证办理
  18. 北航2019计算机学院复试线,2019北京航空航天大学
  19. error: expected ‘}’ at end of input }问题处理
  20. 罗技CSGO压枪宏文件

热门文章

  1. ASP编程入门进阶(九):Application
  2. 【苹果家庭群发推送】软件安装Apple推送是一种基于IMESSAGE平台的新信息推送功效的营销软件
  3. 【ANSYS Workbench】ACT配合Workbench真能替代Mechanical APDL经典命令操作吗?
  4. 利用pandas整理订单,并根据地址对比进行分类
  5. 核心显卡,集成显卡,独立显卡
  6. CTF题记——暑假计划第一周
  7. 聚合和组合关系的代码体现
  8. python一个等号和两个等号_有车以后视频号商业方法论:我们用视频号再造一个公众号...
  9. 基于IPD的测试流程
  10. 青云科技周小四:汽车行业云原生应用初探