在你的C程序中嵌入SpiderMonkey JavaScript引擎

来源:互联网 发布:阿文seo 编辑:程序博客网 时间:2024/05/12 16:41

 原文地址:http://www.mozilla.org/js/spidermonkey/tutorial.html

 Embedding the JavaScript Engine

嵌入JavaScript引擎

A Bare Bones Tutorial

框架教程

Brendan Eich

21 February, 2000

翻译: ked, 时间:2008年3月19日

How to start up the VM and Execute a Script

如何启动虚拟机然后执行一个脚本

Without any error checking for:
说明,我没有检查下面这些错误:
        null returns from JS_ functions that return pointers
        返回指针的 JS_ 函数返回 null
        false returns from JS_ functions that return booleans
        返回 boolean 的 JS_ 函数返回 false
(errors are conventionally saved in a JSBool variable named ok).
(按照惯例, 错误保存在 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: 通常你需要:
     *        a runtime per process, 每个进程需要一个"运行时环境"
     *        a context per thread, 每个线程需要一个"上下文"
     *        a global object per context, 每个"上下文"需要一个全局对象
     *        standard classes (e.g. Date). 标准的类(比如:Date)
     
*/
 
    rt 
= JS_NewRuntime(0x100000); 
    cx 
= JS_NewContext(rt, 0x1000); 
    
global = JS_NewObject(cx, &global_class, NULL, NULL); 
    JS_InitStandardClasses(cx, 
global); 

    
/* 
     * Now suppose script contains some JS to evaluate, say "22/7" as a 
     * bad approximation for Math.PI, or something longer, such as this: 
     * "(function fact(n){if (n <= 1) return 1; return n * fact(n-1)})(5)" 
     * to compute 5! 
    现在, 假设脚本包含了一些要求值的 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 ", JS_GetStringBytes(str));

How to call C functions from JavaScript
如何在JavaScript里调用C的函数

Say the C function is named doit and it would like at least two actual parameters when called (if the caller supplies fewer, the JS engine should ensure that undefined is passed for the missing ones):
假如C函数名称是 doit, 他被调用时有两个实参(如果调用的时候提供的参数不够, JS 引擎会传递 undefined 来替换缺失的参数).
    #define DOIT_MINARGS 2 
    
static JSBool 
    doit(JSContext 
*cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) 
    

        
/* 
         * Look in argv for argc actual parameters, set *rval to return a 
         * value to the caller.          
         * 注意观察实参的参数, 请设置*rval 的值来返回一个值给调用者. 
    
*/
 
        ... 
    }

Then to wire it up to JS, you could write:
然后把它注册到 JS 里, 写法如下:
 ok = JS_DefineFunction(cx, global"doit", doit, DOIT_MINARGS, 0);

Or, if you had a bunch of native functions to define, you would probably put them in a table:
或者, 如果你有很多本地(native)函数要定义, 你可以把他们放到一个表里:

static JSFunctionSpec my_functions[] = 
        
{"doit", doit, DOIT_MINARGS, 00}
        etc... 
        
{0,0,0,0,0}
    }
;
(the final, all-zeroes function specifier terminates the table) and say:
(最后面全为0的函数表示表格结束)然后执行:
ok = JS_DefineFunctions(cx, global, my_functions);

How to call JavaScript functions from C (such as "onClick")
如何在C里面调用 JavaScript 函数(比如:OnClick)

Say the click event is for the top-most or focused UI element at position (x, y):
假设点击事件发生在位置(x,y), 相关对象是 最顶层的或焦点所处的 界面元素:
    JSObject *target, *event
    jsval argv[
1], rval; 
   
/* 
    * Find event target and make event object to represent this click. 
    * Pass cx to NewEventObject so JS_NewObject can be called. 
    找到处于事件位置的目标, 创建一个事件对象(event object )来处理这个事件.
    把 cx 传到 NewEventObject 函数 , 这个函数会就调用 JS_NewObject 函数了.
    
*/
 
    target 
= FindEventTargetAt(cx, global, x, y); 
    
event = NewEventObject(cx, "click", x, y); 
    argv[
0= OBJECT_TO_JSVAL(event); 

    
/* To emulate the DOM, you might want to try "onclick" too. 
     要模拟DOM的话, 你可能也还想尝试调用一下 "onclick".
*/
 
    ok 
= JS_CallFunctionName(cx, target, "onClick"1, argv, &rval); 

    
/* Now test rval to see whether we should cancel the event. 
    现在, 检查一下 rval, 看我们是否可以取消那个事件.
*/
 
    
if (JSVAL_IS_BOOLEAN(rval) && !JSVAL_TO_BOOLEAN(rval)) 
        CancelEvent(
event);
Again, I've elided error checking (such as testing for !ok after the call), and I've faked up some C event management routines that emulate the DOM's convention of canceling an event if its handler returns false. 
再次提醒一下, 上面的代码中, 我省略了错误检查(像调用结束后检查返回值: !ok), 而且, 我虚拟了一个 C 的事件管理程序, 用来仿效 DOM 当事件的操作函数返回false时取消这个事件. 
原创粉丝点击