代码之家  ›  专栏  ›  技术社区  ›  Hasan A Yousef Michael Benjamin

我可以编写可以在WebAssembly、Android和iOS上运行的代码吗[关闭]

  •  -1
  • Hasan A Yousef Michael Benjamin  · 技术社区  · 6 年前

    Rust 可以同时作为WebAssembly、Android和iOS的本机库运行的源代码?

    1 回复  |  直到 6 年前
        1
  •  3
  •   Hasan A Yousef Michael Benjamin    6 年前

    是的,这是可能的,我创建了一个帖子 here 寻求改进建议/想法。

    我的代码,我在这两个测试 wasm android 是:

    src文件夹树:

    Hasans-Air:src h_ajsf$ tree .
    .
    ├── lib.rs
    ├── android
    │   └── mod.rs
    ├── ios
    │   └── mod.rs
    └── wasm
        └── mod.rs
    
    3 directories, 4 files
    

    主要内容:

    // lib.rs
    pub mod wasm;
    pub mod ios;
    pub mod android;
    
    #[cfg(not(target_arch = "wasm32"))]
    use std::os::raw::{c_char};
    
    #[cfg(not(target_arch = "wasm32"))]
    use std::ffi::{CStr};
    
    pub fn rust_greetings(to: &str) -> String {
        format!("Hello {}", to)
    }
    
    #[cfg(not(target_arch = "wasm32"))]
    fn char_str(pattern: *const c_char) -> &'static str {
    
        let c_str = unsafe { CStr::from_ptr(pattern) };
        let string_ptr = match c_str.to_str() {
            Err(_) => "there",
            Ok(string) => string,
        };
        string_ptr
    }
    

    // wasm/mod.rs
    #[cfg(target_arch = "wasm32")]
    pub mod wasm {
        use crate::rust_greetings;
        use wasm_bindgen::prelude::*;
    
        #[wasm_bindgen]
        pub fn wasm_greetings(to: &str) -> String {
            rust_greetings(to)
        }
    }
    

    安卓

    // android/mod.rs
    #[cfg(target_os="android")]
    #[allow(non_snake_case)]
    pub mod android {
        use crate::rust_greetings;
        use crate::char_str;
        extern crate jni;
    
        use self::jni::JNIEnv;
        use self::jni::objects::{JClass, JString};
        use self::jni::sys::{jstring};
    
        #[no_mangle]
        pub unsafe extern fn Java_com_hasan_RustGreetings_greetings(env: JNIEnv, _: JClass, java_pattern: JString) -> jstring {
    
            let jvm_input = env.get_string(java_pattern)
                                            .expect("invalid pattern string").as_ptr();
    
            let input = rust_greetings(char_str(jvm_input));
    
            let output = env.new_string(input)
                                            .expect("Couldn't create java string!");
            output.into_inner()
        }
    }
    

    网间网操作系统

    // ios/mod.rs
    #[cfg(target_os="ios")]
    #[no_mangle]
    pub mod ios {
        use crate::char_str;
    
        use std::ffi::{CString, CStr};
        use std::os::raw::{c_char};
        use crate::rust_greetings;
    
        #[no_mangle]
        pub extern fn ios_greetings(to: *const c_char) -> *mut c_char {
    
            let input = rust_greetings(char_str(to));
    
            CString::new(input).unwrap().into_raw()
        }
    
        pub extern fn iso_greeting_free(s: *mut c_char) {
            unsafe {
                if s.is_null() { return }
                CString::from_raw(s)
            };
        }
    }
    

    汤姆

    # Cargo.toml
    [package]
    name = "greetings"
    version = "0.1.0"
    authors = ["Hasan Yousef"]
    edition = "2018"
    
    [dependencies]
    
    [target.'cfg(target_arch="wasm32")'.dependencies]
    wasm-bindgen = "0.2.29"
    
    [target.'cfg(target_os="android")'.dependencies]
    jni = { version = "0.5", default-features = false }
    
    [lib]
    name = "rust_greetings"
    crate-type = ["cdylib", "dylib", "staticlib"] 
    # Android: dylib
    # iOS: cdylib [armv7s-apple-ios] and staticlib [Others]
    # WASM: cdylib