- 论坛徽章:
- 0
|
嵌入JavaScript引擎梗概教程
Posted by
ShiningRay
on 2nd 四月 2006
嵌入JavaScript引擎
梗概教程
作者:Brendan Eich
2000年2月21日
翻译:
ShiningRay
@
NirvanaStudio
如何启动VM并执行一个脚本
如果不使用任何错误检查这样: JS_起头的返回指针的函数会返回空(null) JS_起头的返回布尔值的函数会返回假(false)(错误照例会被保存在一个JSBool变量ok中)。
JSRuntime *rt;
JSContext *cx;
JSObject *global;
JSClass global_class = {
"global",0,
JS_PropertyStub,JS_PropertyStub,JS_PropertyStub,JS_PropertyStub,
JS_EnumerateStub,JS_ResolveStub,JS_ConvertStub,JS_FinalizeStub
};
/*
* 你必须有:You always need:
* 每个进程一个运行时(runtime),
* 每个线程一个上下文(context),
* 每个上下文有一个全局对象(global),
* 标准类(如Date)。
*/
rt = JS_NewRuntime(0x100000);
cx = JS_NewContext(rt, 0x1000);
global = JS_NewObject(cx, &global_class, NULL, NULL);
JS_InitStandardClasses(cx, global);
/*
*
现在假设脚本包含了要计算的一些JS,比方说像“22/7”Math.PI的
* 不太好的近似值,或者一些更长的东西,像:
*
"(function fact(n){if (n
char *script = "...";
jsval rval;
JSString *str;
JSBool ok;
ok = JS_EvaluateScript(cx, global, script, strlen(script),
filename, lineno, &rval);
str = JS_ValueToString(cx, rval);
printf
("script result: %s\n", JS_GetStringBytes(str));
如何从JavaScript中调用C函数
假设有个C函数叫diot,他在被调用时需要至少两个实参(如果调用者少提供了几个,JS引擎需要保证undefined值传给了那些缺少的参数):
#define DOIT_MINARGS 2
static JSBool
doit(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
/*
* 在argv中查找argc个实参,设置*rval来给调用者返回一个值
*/
...
}
然后把它和JS连接起来,你要写:
ok = JS_DefineFunction(cx, global, "doit", doit, DOIT_MINARGS, 0);
或者,如果你有一堆的本地函数要调用,你可以把它们放在一个表格中:
static JSFunctionSpec my_functions[] = {
{"doit", doit, DOIT_MINARGS, 0, 0},
etc...
{0,0,0,0,0},
};
(最后,全为0的函数表示表格结束)并且用:
ok = JS_DefineFunctions(cx, global, my_functions);
如何从C中调用JavaScript函数(像“onClick”)
假设点击事件是发生在最顶层或者是有焦点的UI元素,位置为(x,y):
JSObject *target, *event;
jsval argv[1], rval;
/*
* 找到事件目标并且产生一个事件对象来表示这个点击。
* 将cx传给NewEventObject这样JS_NewObject就可以被调用了。
*/
target = FindEventTargetAt(cx, global, x, y);
?event = NewEventObject(cx, "click", x, y);
argv[0] = OBJECT_TO_JSVAL(event);
/* 要模拟DOM,你也许还想尝试一下“onclick”*/
ok = JS_CallFunctionName(cx, target, "onClick", 1, argv, &rval);
/* 现在测试rval来看看我们是否需要取消事件. */
if (JSVAL_IS_BOOLEAN(rval) && !JSVAL_TO_BOOLEAN(rval))
CancelEvent(event);
再说一遍,我省略了错误检查(例如在调用之后检查!ok),同时我伪造了一些C的事件管理程序来模拟DOM的协议——如果他的处理程序返回假就取消这个事件。
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/35985/showart_410717.html |
|