SpiderMonkey是Mozilla下的一个开源项目,是用来解析和运行JavaScript脚本的,分JAVA和C两种实现版本。为了能让自己的程序更加灵活和易扩展,加入脚本支撑是一个非常有效的方式。今天尝试了一下把SpiderMonkey加入到自己的程序中,运行了一个简单的脚本。
下载获得js-1.60.tar.gz的tarball并解压,用vc6打开src下的js.mdp,vc6会提示你转换到新版的dsp,然后设定Active Project为win32 release,build,稍等一会就在release目录下得到js32.dll和js32.lib,把这两个文件以及src下的*.h,复制到你的应用程序目录下(或者直接设定你的Project的搜索路径也行)。
附测试代码:
#include <stdio.h>
#define XP_WIN
#include "jsapi.h"
#pragma comment(lib, "js32.lib")
//---------------------------------------------------------------------------
static JSBool my_abs(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval)
{
jsdouble x, z;
if (!JS_ValueToNumber(cx, argv[0], &x)) return JS_FALSE;
z = (x<0) ? -x : x;
return JS_NewDoubleValue(cx, z, rval);
}static JSFunctionSpec my_functions[] = {
{ "abs", my_abs, 1},{0}
};
char* VersionToString(JSVersion v)
{
switch(v) {
case JSVERSION_1_0: return "JavaScript 1.0";
case JSVERSION_1_1: return "JavaScript 1.1";
case JSVERSION_1_2: return "JavaScript 1.2";
case JSVERSION_1_3: return "JavaScript 1.3";
case JSVERSION_1_4: return "JavaScript 1.4";
case JSVERSION_ECMA_3: return "ECMA 262 Edition 3";
case JSVERSION_1_5: return "JavaScript 1.5";
case JSVERSION_DEFAULT: return "Default JavaScript Version";
case JSVERSION_UNKNOWN: return "Unknown JavaScript version";
default: return "Unknown JavaScript version";
}
}
int main()
{
JSVersion version; // 版本号
JSRuntime *rt; // 运行时的内存空间
JSContext *cx; // 环境句柄
JSObject *glob, *it; // 对象(函数,类等)
JSBool builtins;
// 全局对象
JSClass global_class = {
"global",0,
JS_PropertyStub,JS_PropertyStub,JS_PropertyStub,JS_PropertyStub,
JS_EnumerateStub,JS_ResolveStub,JS_ConvertStub,JS_FinalizeStub
};
rt = JS_NewRuntime(8L * 1024L * 1024L);
if (!rt) return 1;
cx = JS_NewContext(rt, 8192);
if (cx == NULL) return 1;
version = JS_GetVersion(cx);
printf("Script Version: %s", VersionToString(version));
glob = JS_NewObject(cx, &global_class, NULL, NULL);
builtins = JS_InitStandardClasses(cx, glob);
JS_DefineFunctions(cx, glob, my_functions);
//JS_DefineFunction(cx, glob, "abs", my_abs, DOIT_MINARGS, 0);
// FILE *fp = fopen("hello.js", "rb");
// char szScript[512];
// fread(buff, 1, 510, fp);
// fclose(fp);
char* szScript = "var today=Date(); today.toString(); var n=2001; n=n+1; var a=-305; abs(a);";
jsval rval;
JSString *str;
char* pFileName = NULL;
int nLines = 0;
if (JS_EvaluateScript(cx, glob, szScript, strlen(szScript), pFileName, nLines, &rval) == JS_FALSE) {
printf("Error Occured while Run Script Engine.\n");
return 1;
}
str = JS_ValueToString(cx, rval); // rval返回脚本最后执行的那个变量的值
printf("Script Result: %s\n", JS_GetStringBytes(str));
JS_DestroyContext(cx);
JS_DestroyRuntime(rt);
JS_ShutDown();
return 0;
}
//---------------------------------------------------------------------------
注:
如果需要让调试器跟踪进如SpiderMonkey的源代码,需要生成debug版的js32.dll和js32.lib。
参考链接:
How to Embed JS Engine.
JavaScript C Engine Embedder’s Guide.
下载地址:
http://ftp.mozilla.org/pub/mozilla.org/js/