zoukankan      html  css  js  c++  java
  • [Rust] Pass a JavaScript Function to WebAssembly and Invoke it from Rust

    In some cases it’s useful to be able to invoke a JavaScript function inside Rust. This session showcases how this can be done, by passing along our JavaScript functions to the WebAssembly module instantiation.

    First let's create a function in js:

          const appendNumberToBody = (number) => {
            const text = document.createTextNode(number);
            document.body.appendChild(text);
          }

    Wrap this function into a single object which contains 'env':

          const importObject = {
            env: {
              appendNumberToBody: appendNumberToBody
            }
          };

    When we load wasm, we can pass in the object:

    WebAssembly.instantiateStreaming(fetch("utils.gc.wasm"), importObject)

    It return a promise, we can run the exported function return by wasm inside the promise.

    Now we are going to create a function in Rust:

    extern {
        fn appendNumberToBody(x: u32);
    }
    
    #[no_mangle]
    pub extern fn run() {
        unsafe { // we need to wrap with unsafe if getting the passed in value from third party
            appendNumberToBody(42);
        }
    }

    We exprot 'run' function, then we can invoke it inside promise:

          WebAssembly.instantiateStreaming(fetch("utils.gc.wasm"), importObject)
          .then(wasmModule => {
              wasmModule.instance.exports.run();
            });

    ---------

    Full code: Github

    index.html:

    <!DOCTYPE html>
    <html>
      <head>
        <script> 
    
          // pass the data from Js to Rust
          const appendNumberToBody = (number) => {
            const text = document.createTextNode(number);
            document.body.appendChild(text);
          }
    
          const importObject = {
            env: {
              appendNumberToBody: appendNumberToBody,
              alert: alert
            }
          };
    
          WebAssembly.instantiateStreaming(fetch("utils.gc.wasm"), importObject)
          .then(wasmModule => {
              wasmModule.instance.exports.run();
            });
        </script>
      <head>
      <body></body>
    <html>

    lib.rs:

    extern {
        fn appendNumberToBody(x: u32);
        fn alert(x: u32);
    }
    
    #[no_mangle]
    pub extern fn run() {
        unsafe {
            appendNumberToBody(42);
            alert(33)
        }
    }
  • 相关阅读:
    vuejs中使用echart图表
    锚点链接
    如何动态修改网页的标题(title)?
    如何为图片添加热点链接?(map + area)
    cookie
    如何为你的网站添加标志性的图标(头像)呢?
    图片拖拽上传至服务器
    js定时器之setTimeout的使用
    input[type=file]中使用ajaxSubmit来图片上传
    input[type=file]样式更改以及图片上传预览
  • 原文地址:https://www.cnblogs.com/Answer1215/p/9823954.html
Copyright © 2011-2022 走看看