SpiderMonkey学习笔记(2)--封装JSAPI

2024-01-26 06:32

本文主要是介绍SpiderMonkey学习笔记(2)--封装JSAPI,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

上一篇文章搭建好了一个简单的SpiderMonkey测试环境,并且把JSAPI User Guide里的样板代码直接拷贝到了工程里。在这篇文章里,我将对JSAPI做一个简单的封装,以方便后续的学习和试验。

1)添加一个C++类,名字估且就叫JsEngine吧

右键点击SpiderMonkeyTest Group,在弹出菜单中点击New Files... 菜单项:

选择iOS -> C and C++ -> C++ Class,然后点Next:

填上JsEngine,然后按Create按钮:

这样一个空白的类就创建好了:

2)设计JsEngine类

我们的JsEngine设计的很简单,除了构造和析构函数,只有一个execJS(...)方法用来执行一段JS脚本:

#include <string>
#include "jsapi.h"class JsEngine {
public:JsEngine();virtual ~JsEngine();void execJS(const std::string& script);
protected:/* JS variables. */JSRuntime *rt;JSContext *cx;JSObject *global;
};

如果不明白JSRuntime、JSContext以及JSObject是什么,建议再看一下JSAPI User Guide,里面讲的很清楚。

3)JsEngine构造函数:初始化SpiderMonkey

#include "JsEngine.h"// =============================================================================
// global_class & reportError
// =============================================================================/* The class of the global object. */
static JSClass global_class = {"global",JSCLASS_GLOBAL_FLAGS,JS_PropertyStub,JS_PropertyStub,JS_PropertyStub,JS_StrictPropertyStub,JS_EnumerateStub,JS_ResolveStub,JS_ConvertStub,NULL,JSCLASS_NO_OPTIONAL_MEMBERS
};/* The error reporter callback. */
static void reportError(JSContext *cx, const char *message, JSErrorReport *report) {fprintf(stderr, "%s:%u:%s\n",report->filename ? report->filename : "<no filename="">",(unsigned int) report->lineno,message);
}// =============================================================================
// JsEngine impl
// =============================================================================JsEngine::JsEngine() {/* Create a JS runtime. */rt = JS_NewRuntime(8L * 1024L * 1024L);if (rt == NULL)return;/* Create a context. */cx = JS_NewContext(rt, 8192);if (cx == NULL)return;JS_SetOptions(cx, JSOPTION_VAROBJFIX | JSOPTION_METHODJIT);JS_SetVersion(cx, JSVERSION_LATEST);JS_SetErrorReporter(cx, reportError);/* Create the global object in a new compartment. */global = JS_NewGlobalObject(cx, &global_class, NULL);if (global == NULL)return;/* Populate the global object with the standard globals,like Object and Array. */if (!JS_InitStandardClasses(cx, global))return;
}

代码稍微有点长(基本上也是从JSAPI User Guide里抄过来的),但实际上并不难理解。先是创建了一个JSRuntime的实例(为其分配了8m内存),然后创建JSContext实例,并告诉它,当脚本解释执行遇到问题的时候,调用reportError函数报告错误紧接着创建出JS Global Object,然后初始化标准的JS类和函数。


4)JsEngine析构函数:清理SpiderMonkey

析构函数比较简单,销毁JSContext和JSRuntime,然后关掉SpiderMonkey引擎:

JsEngine::~JsEngine() {JS_DestroyContext(cx);JS_DestroyRuntime(rt);JS_ShutDown();
}

5)execJS方法

void JsEngine::execJS(const std::string& script) {jsval rval;/*JSBool ok = */JS_EvaluateScript(cx, global, script.c_str(), script.size(),"script", 1, &rval);
}
这个方法也没什么好说的,关于JS_EvaluateScript的详细说明,请看 这里。

6)修改ViewController.mm

最后让我们修改ViewController.mm,测试一下新鲜出炉的JsEngine类:
#import "ViewController.h"
#import "JsEngine.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad
{[super viewDidLoad];// Do any additional setup after loading the view, typically from a nib.JsEngine engine;engine.execJS("alert('Hello World!');");
}- (void)didReceiveMemoryWarning
{[super didReceiveMemoryWarning];// Dispose of any resources that can be recreated.
}@end

7)测试JsEngine

点击Run,在模拟器里运行程序:


看起来一切正常,但是输出窗口中输出了这句话:


不要担心,因为alert()并不是标准的JavaScript函数,只在浏览器环境中才有。而我们的JsEngine并没有实现这个函数,所以,SpiderMonkey报了错。看到这个输出就证明SpiderMonkey顺利解释并执行了我们的HelloWorld脚本。

好吧,先到此为止了,下一篇文章中我们再来看一下怎样实现alert()函数。


这篇关于SpiderMonkey学习笔记(2)--封装JSAPI的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/645915

相关文章

Golang如何对cron进行二次封装实现指定时间执行定时任务

《Golang如何对cron进行二次封装实现指定时间执行定时任务》:本文主要介绍Golang如何对cron进行二次封装实现指定时间执行定时任务问题,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录背景cron库下载代码示例【1】结构体定义【2】定时任务开启【3】使用示例【4】控制台输出总结背景

Python中对FFmpeg封装开发库FFmpy详解

《Python中对FFmpeg封装开发库FFmpy详解》:本文主要介绍Python中对FFmpeg封装开发库FFmpy,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录一、FFmpy简介与安装1.1 FFmpy概述1.2 安装方法二、FFmpy核心类与方法2.1 FF

Go学习记录之runtime包深入解析

《Go学习记录之runtime包深入解析》Go语言runtime包管理运行时环境,涵盖goroutine调度、内存分配、垃圾回收、类型信息等核心功能,:本文主要介绍Go学习记录之runtime包的... 目录前言:一、runtime包内容学习1、作用:① Goroutine和并发控制:② 垃圾回收:③ 栈和

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio

重新对Java的类加载器的学习方式

《重新对Java的类加载器的学习方式》:本文主要介绍重新对Java的类加载器的学习方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、介绍1.1、简介1.2、符号引用和直接引用1、符号引用2、直接引用3、符号转直接的过程2、加载流程3、类加载的分类3.1、显示

一文详解如何在Vue3中封装API请求

《一文详解如何在Vue3中封装API请求》在现代前端开发中,API请求是不可避免的一部分,尤其是与后端交互时,下面我们来看看如何在Vue3项目中封装API请求,让你在实现功能时更加高效吧... 目录为什么要封装API请求1. vue 3项目结构2. 安装axIOS3. 创建API封装模块4. 封装API请求

Java学习手册之Filter和Listener使用方法

《Java学习手册之Filter和Listener使用方法》:本文主要介绍Java学习手册之Filter和Listener使用方法的相关资料,Filter是一种拦截器,可以在请求到达Servl... 目录一、Filter(过滤器)1. Filter 的工作原理2. Filter 的配置与使用二、Listen

鸿蒙中Axios数据请求的封装和配置方法

《鸿蒙中Axios数据请求的封装和配置方法》:本文主要介绍鸿蒙中Axios数据请求的封装和配置方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1.配置权限 应用级权限和系统级权限2.配置网络请求的代码3.下载在Entry中 下载AxIOS4.封装Htt

利用Python快速搭建Markdown笔记发布系统

《利用Python快速搭建Markdown笔记发布系统》这篇文章主要为大家详细介绍了使用Python生态的成熟工具,在30分钟内搭建一个支持Markdown渲染、分类标签、全文搜索的私有化知识发布系统... 目录引言:为什么要自建知识博客一、技术选型:极简主义开发栈二、系统架构设计三、核心代码实现(分步解析

SpringBoot中封装Cors自动配置方式

《SpringBoot中封装Cors自动配置方式》:本文主要介绍SpringBoot中封装Cors自动配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录SpringBoot封装Cors自动配置背景实现步骤1. 创建 GlobalCorsProperties