嵌入JavaScript引擎梗概教程

 

嵌入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 <= 1) return 1; return n *
fact(n-1)})(5)"

* 来计算5!

*/

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的协议——如果他的处理程序返回假就取消这个事件。


Google
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值