• Rust to WebAssembly using js console.log All In One


    Rust to WebAssembly using js console.log All In One

    # build the package
    $  wasm-pack build --target web
    
    <!DOCTYPE html>
    <html lang="zh-Hans">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <meta name="author" content="xgqfrms">
        <meta name="generator" content="VS code">
        <title>Rust to WebAssembly using js console.log All In One</title>
    </head>
    <body>
      <header>
          <h1>Rust to WebAssembly using js console.log All In One</h1>
      </header>
      <main>
          <section>
              <a href="https://www.cnblogs.com/xgqfrms/p/16685185.html">Rust to WebAssembly</a>
          </section>
      </main>
      <footer>
          <p>copyright&copy; xgqfrms 2022</p>
      </footer>
      <script type="module">
        import init, { greet } from "./pkg/rust_to_wasm_npm.js";
        init().then(() => {
          // greet("Rust to WebAssembly and run wasm in js ");
          console.log('greet =', greet);
          greet("Rust to WebAssembly and run wasm in js ");
          // greet.log("Rust to WebAssembly and run wasm in js ");
        });
      </script>
    </body>
    </html>
    
    

    console.log ❌

    // ✅ Cargo.toml 中 dependencies 配置后,无需再次手动导入外部包 external crate
    
    // 导入外部包 external crate
    // extern crate wasm_bindgen;
    
    // 引入 wasm_bindgen::prelude 的全部模块 *
    use wasm_bindgen::prelude::*;
    
    // 使用 wasm-bindgen 在 Rust 与 JavaScript 之间通信
    
    /*
    
    wasm-pack 使用另一个工具 wasm-bindgen 来提供 JavaScript 和 Rust 类型之间的桥梁。
    它允许 JavaScript 使用字符串调用 Rust API,或调用 Rust 函数来捕获 JavaScript 异常。
    
    */
    
    // 从 Rust 调用 JavaScript 中的外部函数
    // #[] => 属性, 修改下一条语句 extern; 即,告诉 rust 调用一些外部定义的函数, wasm-bindgen 知道如何找到这些函数
    #[wasm_bindgen]
    extern {
      // 函数签名 (参数名:参数类型)
      // pub fn alert(s: &str);
      // let console_log = console.log;
      // pub fn console_log(s: &str);
      // pub fn console.log(s: &str);
      pub fn console(s: &str);
    }
    
    // 生成 JavaScript 可以调用的 Rust 函数
    // #[] => 属性, 修改下一条语句 fn; 即,这个 Rust 函数能够被 JavaScript 调用
    // public => pub
    #[wasm_bindgen]
    pub fn greet(name: &str) {
      // &format!, 字符串格式化,即字符串插值
      // alert(&format!("Hello, {}!", name));
      // console_log(&format!("Hello, {}!", name));
      // console.log(&format!("Hello, {}!", name));
      console(&format!("Hello, {}!", name));
    }
    
    

    alert

    // ✅ Cargo.toml 中 dependencies 配置后,无需再次手动导入外部包 external crate
    
    // 导入外部包 external crate
    // extern crate wasm_bindgen;
    
    // 引入 wasm_bindgen::prelude 的全部模块 *
    use wasm_bindgen::prelude::*;
    
    // 使用 wasm-bindgen 在 Rust 与 JavaScript 之间通信
    
    /*
    
    wasm-pack 使用另一个工具 wasm-bindgen 来提供 JavaScript 和 Rust 类型之间的桥梁。
    它允许 JavaScript 使用字符串调用 Rust API,或调用 Rust 函数来捕获 JavaScript 异常。
    
    */
    
    // 从 Rust 调用 JavaScript 中的外部函数
    // #[] => 属性, 修改下一条语句 extern; 即,告诉 rust 调用一些外部定义的函数, wasm-bindgen 知道如何找到这些函数
    #[wasm_bindgen]
    extern {
      // 函数签名 (参数名:参数类型)
      pub fn alert(s: &str);
    }
    
    // 生成 JavaScript 可以调用的 Rust 函数
    // #[] => 属性, 修改下一条语句 fn; 即,这个 Rust 函数能够被 JavaScript 调用
    // public => pub
    #[wasm_bindgen]
    pub fn greet(name: &str) {
      // &format!, 字符串格式化,即字符串插值
      alert(&format!("Hello, {}!", name));
    }
    
    

    solutions

    
    #![allow(unused_variables)]
    fn main() {
    use wasm_bindgen::prelude::*;
    
    #[wasm_bindgen(start)]
    pub fn run() {
        bare_bones();
        using_a_macro();
        using_web_sys();
    }
    
    // First up let's take a look of binding `console.log` manually, without the
    // help of `web_sys`. Here we're writing the `#[wasm_bindgen]` annotations
    // manually ourselves, and the correctness of our program relies on the
    // correctness of these annotations!
    
    #[wasm_bindgen]
    extern "C" {
        // Use `js_namespace` here to bind `console.log(..)` instead of just
        // `log(..)`
        #[wasm_bindgen(js_namespace = console)]
        fn log(s: &str);
    
        // The `console.log` is quite polymorphic, so we can bind it with multiple
        // signatures. Note that we need to use `js_name` to ensure we always call
        // `log` in JS.
        #[wasm_bindgen(js_namespace = console, js_name = log)]
        fn log_u32(a: u32);
    
        // Multiple arguments too!
        #[wasm_bindgen(js_namespace = console, js_name = log)]
        fn log_many(a: &str, b: &str);
    }
    
    fn bare_bones() {
        log("Hello from Rust!");
        log_u32(42);
        log_many("Logging", "many values!");
    }
    
    // Next let's define a macro that's like `println!`, only it works for
    // `console.log`. Note that `println!` doesn't actually work on the wasm target
    // because the standard library currently just eats all output. To get
    // `println!`-like behavior in your app you'll likely want a macro like this.
    
    macro_rules! console_log {
        // Note that this is using the `log` function imported above during
        // `bare_bones`
        ($($t:tt)*) => (log(&format_args!($($t)*).to_string()))
    }
    
    fn using_a_macro() {
        console_log!("Hello {}!", "world");
        console_log!("Let's print some numbers...");
        console_log!("1 + 3 = {}", 1 + 3);
    }
    
    // And finally, we don't even have to define the `log` function ourselves! The
    // `web_sys` crate already has it defined for us.
    
    fn using_web_sys() {
        use web_sys::console;
    
        console::log_1(&"Hello using web-sys".into());
    
        let js: JsValue = 4.into();
        console::log_2(&"Logging arbitrary values looks like".into(), &js);
    }
    
    }
    
    

    https://rustwasm.github.io/wasm-bindgen/examples/console-log.html

    #[wasm_bindgen]
    extern "C" {
        // Use `js_namespace` here to bind `console.log(..)` instead of just
        // `log(..)`
        #[wasm_bindgen(js_namespace = console)]
        fn log(s: &str);
    
        // The `console.log` is quite polymorphic, so we can bind it with multiple
        // signatures. Note that we need to use `js_name` to ensure we always call
        // `log` in JS.
        #[wasm_bindgen(js_namespace = console, js_name = log)]
        fn log_u32(a: u32);
    
        // Multiple arguments too!
        #[wasm_bindgen(js_namespace = console, js_name = log)]
        fn log_many(a: &str, b: &str);
    }
    
    fn bare_bones() {
        log("Hello from Rust!");
        log_u32(42);
        log_many("Logging", "many values!");
    }
    
    

    https://stackoverflow.com/questions/66836479/calling-console-log-from-rust-wasm32-wasi-without-the-need-for-ssvm-ssvmup

    https://www.webassemblyman.com/rustwasm/how_to_log_to_the_console_in_rust_webassembly.html

    use log::{error, info, warn};
    use wasm_bindgen::prelude::*;
    use wasm_bindgen_console_logger::DEFAULT_LOGGER;
    
    #[wasm_bindgen]
    pub fn start() {
        log::set_logger(&DEFAULT_LOGGER).unwrap();
        log::set_max_level(log::LevelFilter::Info);
    
        error!("Error message");
        warn!("Warning message");
        info!("Informational message");
    }
    
    

    https://docs.rs/wasm-bindgen-console-logger/latest/wasm_bindgen_console_logger/

    test ✅

    js_namespace 和 js_name

    
    #[wasm_bindgen]
    extern "C" {
      // Use `js_namespace` here to bind `console.log(..)` instead of just `log(..)`
      // 自定义 js name ✅ js_namespace 和 js_name 必须是 js 中真实存在的 ✅
      #[wasm_bindgen(js_namespace = console, js_name = log)]
      // fn log(s: &str);
      fn console_log(s: &str);
    
      // The `console.log` is quite polymorphic, so we can bind it with multiple signatures.
      // Note that we need to use `js_name` to ensure we always call `log` in JS.
      #[wasm_bindgen(js_namespace = console, js_name = log)]
      fn log_u32(a: u32);
    
      // Multiple arguments too!
      #[wasm_bindgen(js_namespace = console, js_name = log)]
      fn log_strs(a: &str, b: &str);
    }
    
    
    
    #[wasm_bindgen]
    pub fn greet(name: &str) {
      // &format!, 字符串格式化,即字符串插值
      let string: &str = &format!("Hello, {}!", name);
      // log(string);
      console_log("自定义 js name ✅ js_namespace 和 js_name 必须是 js 中真实存在的 ✅\n");
      console_log(string);
    }
    
    #[wasm_bindgen]
    pub fn greet_u32(num: u32) {
      // &format!, 字符串格式化,即字符串插值
      log_u32(num);
    }
    
    
    #[wasm_bindgen]
    pub fn greet_strs(str1: &str, str2: &str) {
      // &format!, 字符串格式化,即字符串插值
      let string1: &str = &format!("Hello, {}!", str1);
      let string2: &str = &format!("\nThis year is {}!", str2);
      log_strs(string1, string2);
    }
    
    
    

    refs

    https://developer.mozilla.org/en-US/docs/WebAssembly/Rust_to_wasm



    ©xgqfrms 2012-2020

    www.cnblogs.com/xgqfrms 发布文章使用:只允许注册用户才可以访问!

    原创文章,版权所有©️xgqfrms, 禁止转载 ️,侵权必究⚠️!


  • 相关阅读:
    四大组件之BroadcastReceiver基础
    SQLiteOpenHelper与SQLiteDatabase的使用
    SharedPreferences实现保存用户名功能
    Fragment加载方式与数据通信
    ProgressBar、ProgessDialog用法解析
    GridView添加事件监听和常用属性解析
    ListView添加item的事件监听
    ArrayAdapter、SimpleAdapter简单用法
    MySQL入门笔记(二)
    MySQL入门笔记(一)
  • 原文地址:https://www.cnblogs.com/xgqfrms/p/16685185.html
Copyright © 2020-2023  润新知