android - 我可以编写可以在 WebAssembly 以及 Android 和 iOS 上运行的 Rust 代码吗?

标签 android ios rust webassembly

<分区>

是否可以写成common Rust可以同时作为 WebAssembly、Android 和 iOS 的 native 库运行的源代码?

最佳答案

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

我在 wasmandroid 上测试的代码是:

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

// 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

// 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)
        };
    }
}

TOML

# 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

关于android - 我可以编写可以在 WebAssembly 以及 Android 和 iOS 上运行的 Rust 代码吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53750506/

相关文章:

Android:如何找出窃取我的触摸事件的 View ?

IOS Twilio IP 消息系统初始集成步骤

ios - 如何使用 swift 遍历目录中的多个(音频/mp3)文件? - Swift, iOS8 Soundboard AVPlayer

rust - 匹配浮点范围的替代方法

android - 如何将表情符号有意发送到whatsapp?

android - 在自定义警报对话框中创建 Android 透明布局

android - 如何像媒体编码器中的语音调用(上行链路+下行链路)一样并行地合并两个音频文件。安卓

ios - UICollectionView 中的画外音 - 缺少一些翻译

timer - 如何使用 Tokio 产生许多可取消的计时器?

string - 如何将 f64 转换为 String 并解析回 f64?