Tag Archives: C语言

JavaScript-C引擎嵌入开发指南

JavaScript-C引擎嵌入开发指南 翻译:ShiningRay@Nirvana Studio原文地址:http://www.mozilla.org/js/spidermonkey/apidoc/jsguide.html JavaScript-C引擎概览 本文档提供了一个JavaScript(JS)引擎的C语言实现的概述,他介绍了你如何在你的应用程序中嵌入脚本引擎来让它们可以使用JS。有两大理由让你在应用程序中嵌入JS引擎:使用脚本来自动操作你的应用程序;同时使用JS引擎和脚本无论何时都可以提供跨平台的功能并消除了应用程序解决方案对平台的依赖性。 受支持的JavaScript版本 本JS引擎支持从JS 1.0版到JS1.4。JS 1.3和更高版本符合ECMAScript-262规范。JS引擎解析、编译和执行包含JS语句和函数的脚本。这个引擎可以处理要用来执行脚本的JS数据类型和对象内存分配,同时它可以清除——垃圾回收——内存中已经不需要的数据类型和对象。 你如何使用这个引擎? 通常,你将JS引擎作为一个共享的资源进行构建。例如,在Windows和Windows NT上,这个引擎是一个DLL文件,在Unix上是一个共享库。然后你把你的应用程序和他连接,同时嵌入式JS引擎应用程序编程接口(API)就可以在你的应用程序中调用了。JS引擎的API提供了以下几种分类的函数: 数据类型操作 运行时控制 类和对象创生的维护 函数和脚本执行 字符串处理 错误处理 安全性控制 调试支持 你在每个嵌入了JS调用的应用程序中将会用到这些功能分类中的某些部分,象运行时控制和数据类型操作。例如,在你调用其他JS功能之前,你必须通过调用JS_NewRuntime函数来新建和初始化JS引擎。其他功能分类,像安全控制,提供一些可选的特性,你可以根据需要在你的应用程序中使用它们。 这个引擎和应用程序有什么关系? 从概念上来讲,JS引擎在你的系统上是一个共享资源。通过在你的应用程序中嵌入引擎API命令你可以向JS引擎传递处理的请求。这个引擎,反过来,处理你的请求,并把返回值或者状态信息返回给你的应用程序。图1.1描述了它们一般的关系: 图 1.1 例如,假设你正在使用JS引擎来使你的应用程序能通过JS脚本自动运行,同时假设你的应用程序运行一个脚本来对一个用户进行身份验证并且设置一个用户对这个应用程序的访问权限。首先,你的应用程序可能新建一个代表用户的自定义JS对象,包括了用户的名字、ID、访问权限和一个可能的用户拥有权限在应用程序中使用的函数的列表。 在这个情况下,你的应用程序给JS引擎发送的的第一个请求可能是对JS_NewObject的调用来新建一个自定义对象。当JS引擎新建了这个对象,他返回一个指针给你的应用程序。你的应用程序可以再次调用JS引擎来执行使用这个对象的脚本。例如,在建立了用户对象之后,你的应用程序会立刻给JS_EvaluateScript传递一个脚本来立刻编译执行。那个脚本可以获得并验证用户信息,然后建立用户对其他应用程序特性的访问权限。 事实上,你的应用程序和JS引擎之间的关系远比图1.1中显示的要复杂的多。例如,它假设你已经为你的平台构建了JS引擎。它还假设你的应用程序包含了jsapi.h还假设应用程序对引擎进行的第一个调用已经初始化了JS运行时。 当JS引擎接受到了一个初始化的请求时,他会为JS运行时分配内存。图1.2描述了这个过程: 图 1.2 这个运行时是一个内存空间,在其中可以维护你的应用程序所使用的变量、对象和上下文。一个上下文是指,针对JS引擎所使用的线程的脚本执行状态。每个同时存在的脚本或者线程都必须有它自己的上下文。一个单独的JS运行时可以包含很多上下文、对象和变量。 几乎所有的JS引擎调用都要求有一个上下文的参数,所以在创建了运行时之后你的应用程序首先要做的一件事情是调用JS_NewContext来至少创建一个上下文。实际你需要的上下文数量由你的应用程序中所期望同时运行的脚本的数量决定。从另一方面说,如果同一时间只有一个脚本被编译执行,那么你就知需要建立单独的一个上下文,你可以对每个脚本重复使用它。 在你新建了上下文之后,你会通常想要初始化引擎内置的JS对象,可以通过调用JS_InitStandardClasses实现。内置的对象有Array,Boolean,Date,Math,Number,和String字符串对象,大多数脚本都会用到。 大多数应用程序也要用到自定义JS对象。这些对象是特定于你的应用程序的。他们通常代表了数据结构和应用程序中脚本使用的方法。要新建一个自定义对象,你要组装一个JS类来生成这个对象,调用JS_InitClass来在运行时设立这个类,然后调用JS_NewObject来在引擎中新建你这个自定义对象的实例。最后,如果你的对象有一些属性,你也许要通过调用JS_SetProperty来设置他们的默认值。 即使你在创建一个对象的时候给JS引擎传递了一个特定的上下文,最后这个对象还是独立于这个上下文存在的。任何脚本都可以和任意上下文相关联来访问任何对象。图1.3描述了脚本和运行时、上下文以及对象之间的关系。 图 1.3 如图1.3所示,脚本和上下文完全是互相独立存在的及时他们可以访问相同的对象。在给定的运行时中,一个应用程序可以任意未分配的上下文来访问任何对象。也可能有时你想确保能为独占的使用而保留某些上下文和对象。在这些情况下,给你的应用程序新建单独的运行时:一个针对共享上下文和对象,另一个(或者更多的,取决于你的应用程序的需求)针对私有的运行时和对象。 注意:同一时间只能有一个线程被授权访问特定上下文。 构建引擎 在你可以在你的应用程序中使用JS之前,你必须将JS引擎构建成一个可共享的库。在大多数情况下,引擎代码已经包括了Make文件来自动构建。 例如,在Unix下,js源代码目录包括了一个基本的Gnu Make文件——Makefile.ref和一个config目录。config目录包括了平台特定的.mk文件来配合Makefile.ref对你的环境进行构建。在Windows NT下,NMake文件是js.mak。 请阅读源代码目录中任何的readme文件,也许其中包括了和更新的编译指导或者其他信息。 嵌入引擎有什么必要条件? 如果要让你的应用程序可以执行JS,就要在你的应用程序代码中嵌入合适的引擎。嵌入一般有五步: 在你的C模块中加入#include jsapi.h来确保编译器知道有哪些引擎的API可以调用。极少部分特殊的JS引擎工作时会要求你包含额外的头文件。例如,要在你的应用程序中调用JS调试器,你要在合适的模块里面包含jsdbgapi.h。 大部分在JS源代码中的其它的头文件不应该被引用。这样做可能会使你的程序依赖于引擎内部的接口,而这些接口可能随着版本发布而更改。 在你的应用程序中提供支持结构和变量声明。例如,如果你打算给JS引擎传递一个脚本呢,提供一个字符串变量保存了你的应用程序的脚本的版本的文字信息。使用jsapi.h中定义的JS数据类型来声明结构和变量。 使用JavaScript编写特定应用的对象。这些对象常常会与操作在你C程序中的结构的结构和方法进行通讯,特别是如果你在使用JS引擎来自动操作你的应用程序。 在程序代码中嵌入合适的JS引擎API调用和变量引用,包括初始化内置JS对象,和创建组成任何应用程序要用的自定义对象。 大多数JS引擎调用都会返回一个值。如果这个值是零或者空,它通常表示一个错误的情况发生了。如果值非零,它一般表示成功;在这些情况下,返回的值常常会是你的程序需要使用的指针,或者存起来留以后引用。很重要的是,你的程序至少应该每次检查JS调用返回的值。 [...]