首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将对象数组传递给WebAssembly,并将其转换为具有wasm-bindgen的结构向量?

如何将对象数组传递给WebAssembly,并将其转换为具有wasm-bindgen的结构向量?
EN

Stack Overflow用户
提问于 2018-10-13 18:52:19
回答 1查看 8.2K关注 0票数 21

可以传递这样的整数数组:

代码语言:javascript
复制
const js = import("./webassembly_rust");
let array_nums = [1,2,3,4,5,6,7,8,9];

js.then(js => {
  js.test( array_nums );
}); 

以WebAssembly并将其保存在如下向量中:

代码语言:javascript
复制
extern crate serde_json;
extern crate wasm_bindgen;

use wasm_bindgen::prelude::*;

#[macro_use]
extern crate serde_derive;

#[wasm_bindgen]
pub fn test(array: JsValue) {
    let elements: Vec<u32> = array.into_serde().unwrap();
}

还可以传递这样的单个对象:

代码语言:javascript
复制
const js = import("./webassembly_rust");
let jsObject = {name: "hello world", id: "99", parent_id: "11"};

js.then(js => {
  js.test( jsObject );
}); 

要将WebAssembly保存为Element结构,如下所示:

代码语言:javascript
复制
extern crate serde_json;
extern crate wasm_bindgen;

use wasm_bindgen::prelude::*;

#[macro_use]
extern crate serde_derive;

#[derive(Serialize, Deserialize)]
pub struct Element {
    name: String,
    id: String,
    parent_id: String,
}

#[wasm_bindgen]
pub fn test(js_object: &JsValue) {
    let element: Element = js_object.into_serde().unwrap();
}

接下来我尝试传递这样的对象数组:

代码语言:javascript
复制
const js = import("./webassembly_rust");
let arrayOfObjects = [
  {name: "hello world", id: "99", parent_id: "88"},
  {name: "hello world2", id: "88", parent_id: "12"},
  {name: "hello world3", id: "77", parent_id: "88"}
]

js.then(js => {
  js.test( arrayOfObjects );
}); 

要将WebAssembly保存为Element结构的向量,如下所示:

代码语言:javascript
复制
extern crate serde_json;
extern crate wasm_bindgen;

use wasm_bindgen::prelude::*;

#[macro_use]
extern crate serde_derive;

#[derive(Serialize, Deserialize)]
pub struct Element {
    name: String,
    id: String,
    parent_id: String,
}

#[wasm_bindgen]
pub fn test(js_objects: &JsValue) {
    let elements: Vec<Element> = js_objects.into_serde().unwrap();
}

这是编译的,但是当我运行这段代码时,我会得到以下错误:

代码语言:javascript
复制
func $__rust_start_panic (param i32) (result i32)
  unreachable
  unreachable
end

传递一个包含数字的对象数组,如下所示:

代码语言:javascript
复制
const js = import("./webassembly_rust");
let arrayOfNumObjects = [
    {name: 1, id: 2, parent_id: 3 },
    {name: 1, id: 2, parent_id: 3 },
    {name: 1, id: 2, parent_id: 3 }
]

js.then(js => {
  js.test( arrayOfNumObjects );
}); 

如果Element结构只包含u32值,则可以使用u32

代码语言:javascript
复制
extern crate serde_json;
extern crate wasm_bindgen;

use wasm_bindgen::prelude::*;

#[macro_use]
extern crate serde_derive;

#[derive(Serialize, Deserialize)]
pub struct Element {
    name: u32,
    id: u32,
    parent_id: u32,
}

#[wasm_bindgen]
pub fn test(js_objects: &JsValue) {
    let elements: Vec<Element> = js_objects.into_serde().unwrap();
}

这个问题似乎是由String结构中的Element类型引起的。

我做错什么了?

我找到了以下文章,但我找不到解决问题的办法:

  • 与塞德 这说明了如何将JavaScript对象转换为结构,但不解释如何将对象数组转换为结构向量。
  • sys箱 这个机箱允许使用JavaScript类型,如Rust中的数组或对象,但这不是我想要的。我想将JavaScript值转换为对应的锈蚀值。据我所知,这个板条箱只允许在铁锈中使用JavaScript。这不像使用铁锈那么快。
  • github问题
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-10-15 14:47:23

按照说明获得基本锈蚀/ WASM设置,然后添加对通过Serde的任意数据的支持。

我已经更改了您的代码,以返回一个数字并打印出该数字,只是为了确保它正常工作。

Cargo.toml

代码语言:javascript
复制
[package]
name = "ww"
version = "0.1.0"
authors = ["An Devloper <an.devloper@example.com>"]
edition = "2018"

[lib]
crate-type = ["cdylib"]

[dependencies]
wasm-bindgen = { version = "0.2", features = ["serde-serialize"] }
serde_json = "1.0.32"
serde_derive = "1.0.80"
serde = "1.0.80"

src/lib.rs

代码语言:javascript
复制
extern crate serde_json;
extern crate wasm_bindgen;

use wasm_bindgen::prelude::*;

#[macro_use]
extern crate serde_derive;

#[derive(Serialize, Deserialize)]
pub struct Element {
    name: String,
    id: String,
    parent_id: String,
}

#[wasm_bindgen]
pub fn test(js_objects: &JsValue) -> i32 {
    let elements: Vec<Element> = js_objects.into_serde().unwrap();
    elements
        .iter()
        .map(|e| {
            let id = e.id.parse::<i32>().unwrap_or(0);
            let parent_id = e.parent_id.parse::<i32>().unwrap_or(0);
            id + parent_id
        })
        .sum()
}

index.js

代码语言:javascript
复制
const js = import("./ww");

let arrayOfObjects = [
  { name: "hello world", id: "99", parent_id: "88" },
  { name: "hello world2", id: "88", parent_id: "12" },
  { name: "hello world3", id: "77", parent_id: "88" },
]

js.then(js => {
  const sum = js.test(arrayOfObjects);
  console.log(sum);
});

package.json

代码语言:javascript
复制
{
  "scripts": {
    "serve": "webpack-dev-server"
  },
  "devDependencies": {
    "html-webpack-plugin": "^3.2.0",
    "webpack": "^4.0.1",
    "webpack-cli": "^3.1.1",
    "webpack-dev-server": "^3.1.0"
  }
}

webpack.config.js

代码语言:javascript
复制
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: "./index.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "index.js",
  },
  plugins: [
    new HtmlWebpackPlugin({
      title: "Getting started with WASM"
    })
  ],
  mode: "development"
};

然后跑:

代码语言:javascript
复制
# once
npm install
# every time the code changes
cargo +nightly build --target wasm32-unknown-unknown
wasm-bindgen target/wasm32-unknown-unknown/debug/*.wasm --out-dir .
npm run serve

访问启用WASM浏览器中的页面。

有观察力的读者会注意到,我没有做任何与OP不同的事情。那是因为这段代码已经按原样工作了。每次更改锈蚀代码时,请确保:

  1. 构建您的锈蚀代码
  2. 重新运行
票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52796222

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档