• [WASM] Access WebAssembly Memory Directly from JavaScript


    While JavaScript has a garbage-collected heap, WebAssembly has a linear memory space. Nevertheless using a JavaScript ArrayBuffer, we can read and write to WebAssembly’s memory space.

    lib.rs:

    #[macro_use]
    extern crate cfg_if;
    
    extern crate wasm_bindgen;
    use wasm_bindgen::prelude::*;
    
    cfg_if! {
        // When the `console_error_panic_hook` feature is enabled, we can call the
        // `set_panic_hook` function to get better error messages if we ever panic.
        if #[cfg(feature = "console_error_panic_hook")] {
            extern crate console_error_panic_hook;
            use console_error_panic_hook::set_once as set_panic_hook;
        }
    }
    
    cfg_if! {
        // When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
        // allocator.
        if #[cfg(feature = "wee_alloc")] {
            extern crate wee_alloc;
            #[global_allocator]
            static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
        }
    }
    
    // Definitions of the functionality available in JS, which wasm-bindgen will
    // generate shims for today (and eventually these should be near-0 cost!)
    //
    // These definitions need to be hand-written today but the current vision is
    // that we'll use WebIDL to generate this `extern` block into a crate which you
    // can link and import. There's a tracking issue for this at
    // https://github.com/rustwasm/wasm-bindgen/issues/42
    //
    // In the meantime these are written out by hand and correspond to the names and
    // signatures documented on MDN, for example
    #[wasm_bindgen]
    extern "C" {
        type HTMLDocument;
        static document: HTMLDocument;
        #[wasm_bindgen(method)]
        fn createElement(this: &HTMLDocument, tagName: &str) -> Element;
        #[wasm_bindgen(method, getter)]
        fn body(this: &HTMLDocument) -> Element;
    
        type Element;
        #[wasm_bindgen(method, setter = innerHTML)]
        fn set_inner_html(this: &Element, html: &str);
        #[wasm_bindgen(method, js_name = appendChild)]
        fn append_child(this: &Element, other: Element);
        #[wasm_bindgen(js_namespace = console)]
        fn log(msg: &str);
    }
    
    macro_rules! log {
        ($($t:tt)*) => (log(&format!($($t)*)))
    }
    View Code
    #[wasm_bindgen]
    pub struct Color {
        red: u8,
        green: u8,
        blue: u8,
    }
    
    #[wasm_bindgen]
    pub struct Image {
        pixels: Vec<Color>,
    }
    
    #[wasm_bindgen]
    impl Image {
        pub fn new() -> Image {
            let color1 = Color {
                red: 255,
                green: 0,
                blue: 0,
            };
            let color2 = Color {
                red: 60,
                green: 70,
                blue: 90,
            };
            let pixels = vec![color1, color2];
            Image {
                pixels
            }
        }
    
        pub fn pixels_ptr(&self) -> *const Color {
            self.pixels.as_ptr()
        }
    }

    We create a Image object, which has two functions, new() and pixels_ptr() which can be called by javascript. new() is a constructor function, pixels_ptr() is a instant method.

    app.js:

    import { memory } from "../crate/pkg/rust_webpack_bg";
    import { Image } from "../crate/pkg/rust_webpack";
    
    const image = Image.new();
    const pixelsPointer = image.pixels_ptr();
    const pixels = new Uint8Array(memory.buffer, pixelsPointer, 6);
    console.log(pixels);
    
    function numToHex(value) {
        const hex = value.toString(16);
        return hex.length === 1 ? `0${hex}` : hex;
      }
      
      function drawPixel(x, y, color) {
        const ctx = canvas.getContext("2d");
        ctx.fillStyle = `#${numToHex(color[0])}${numToHex(color[1])}${numToHex(
          color[2]
        )}`;
        ctx.fillRect(x, y, 100, 100);
      }
      
      const canvas = document.createElement("canvas");
      document.body.appendChild(canvas);
      drawPixel(0, 0, pixels.slice(0, 3));
      drawPixel(100, 0, pixels.slice(3, 6));
  • 相关阅读:
    搭建个人Spring-Initializr服务器
    “不蒜子”统计总访问人数脚本
    基于Hazelcast及Kafka实现的分布式锁与集群负载均衡
    虚拟机部署hadoop集群
    程序员、黑客及开发者之间的区别
    今日校园自动登录教程
    逆向DES算法
    来自穷逼对HttpCanary的蹂躏
    今日校园提交签到和查寝-Java实现
    JS 判断数据类型方法
  • 原文地址:https://www.cnblogs.com/Answer1215/p/9919993.html
Copyright © 2020-2023  润新知