javascript - GraalVM 如何将数组从方法返回到客户语言?

我在 OpenJDK 17 中使用 GraalVM (Truffle),想知道从方法调用中将 values 返回到来宾语言的正确方法是什么?现在我正在努力传递一个 String[] 数组回来。

例子:

Java(主机)

class Services
{
    Value message;

    @HostAccess.Export
    public String[] getArrayString()
    {
        return new String[]{"s1", "s2", "s3"};
    }

    @HostAccess.Export
    public void setMessage( Value v )
    {
        message = v;
        message.pin();
    }
}

...

String jsScript = " ... " // see below
try ( Context context = Context.newBuilder().allowHostAccess(HostAccess.SCOPED).build() )
{
    Services s = new Services();
    context.getBindings("js").putMember("services", s);
    context.eval("js", jsScript);
}

JavaScript(客人)

var a = services.getArrayString();
b = '';
for ( var c in a ) b += c;
services.setMessage('' + a + ' // ' + b)

最后的消息 value 是 "[object Object] // " (b 为空白),但我期望像 "[object Object] // s1s2s3" 这样的消息。

我也尝试过返回类型 Object[]ArrayList<String>。我不确定为什么我不能访问数组的元素,要么我没有正确地传回数组,要么我没有在 JavaScript 脚本中正确访问它。我在 GraalVM 文档中找到的示例始终是关于将 values 从主机直接传递给来宾,但我想通过方法调用来实现 - 这是如何完成的?

回答1

我终于找到了一种将数组从主机传递给来宾的方法——使用 ProxyArray

https://www.graalvm.org/22.1/reference-manual/embed-languages/#computed-arrays-using-polyglot-proxies

通过阅读 Graalvm 文档并尝试他们提供的非常原始的示例,我对 Services 类进行了以下更改:

ArrayList<String> array = new ArrayList<String>();

    @HostAccess.Export
    public void prepareList()
    {
        array.add("s1");
        array.add("s2");
        array.add("s3");
    }

    @HostAccess.Export
    public ProxyArray getArray()
    {
        return new ProxyArray() {

            @Override
            public Object get( long index )
            {
                return array.get((int)index);
            }

            @Override
            public void set( long index, Value value )
            {
                // TODO Auto-generated method stub
            }

            @Override
            public long getSize()
            {
                return array.size();
            }
        };
    }

最后来宾电话看起来像这样:

services.prepareList();
var a = services.getArray();
b = '';
for ( i = 0; i < a.length; i++ ) b += a[i];
services.setMessage('' + a + ' // ' + b)

然后消息的 value 与预期的一样 "[object Object] // s1s2s3"

希望有人觉得这很有用……如果您有更好的返回对象(数组、哈希表等)的方法,请在此处发布您的答案-谢谢。

相似文章

随机推荐

最新文章