Rhino中如何创建原生函数?

4
我一直在查看Rhino的文档源代码,试图找到实现自己全局本地函数的线索。但是这项任务比我预期的要复杂。

阅读RingoJS中require函数实现的代码后,我相信我需要按照以下方式进行操作:

import org.mozilla.javascript.BaseFunction;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.Context;

public class MyGlobalNativeFunction extends BaseFunction {
    public MyGlobalNativeFunction() {}

    public Object call(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) {
        // implementation of my function
    }

    public int getArity() {
        return 1;
    }
}

我是否走在正确的道路上?提供一步一步的指南将会非常有帮助。

如果我能使用Rhino的defineClass函数来创建全局本地函数,那就太好了。我不太想推出自己修改过的Rhino版本,只是因为我想实现一个本地函数。

2个回答

4

我认为这应该可行,如果你只想实现一个全局函数,那么这是一个不错的方法。如果你想要实现多个函数或主机对象,还有其他方法。

然后,您可以使用以下内容来实例化您的函数:

scope.defineProperty("myNativeFunction",
                     new MyGlobalNativeFunction(),
                     ScriptableObject.DONTENUM);

查看RingoGlobal,了解如何完成此操作(它还展示了如何在不必为每个函数创建类的情况下一次定义多个函数)。Rhino示例目录包含一些使用Rhino创建正确主机对象的示例。


我假设 scope 是全局作用域,对吗?我应该在哪里实例化它,如何访问scope?我看到 RingoGlobal 有一个叫做 init 的方法。 - Aadit M Shah

4
首先,您需要初始化全局范围(初始化所有Javascript标准对象、函数等),接下来按照Hannes Wallnöfer的方法向该范围添加您的函数。
Context cx = Context.enter();  //enter rhino context - bind context with current thread
Scriptable globalScope= cx.initStandardObjects();  //init js standard object in global scope
globalScope.defineProperty("myNativeFunction",
                     new MyGlobalNativeFunction(),
                     ScriptableObject.DONTENUM);

就是这样了。

现在调用这个函数需要使用invoke:

Object result = cx.evaluateString(globalScope, "myNativeFunction()", "<cmd>", 1, null);

更多信息请参见:Rhino嵌入教程


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接