ioséçºã«Rustã使ã ç°å¢æ§ç¯ç·¨
iOSã§ã¯ãObjective-Cï¼C++ãæ¸ããï¼ãSwiftããã使ãã¾ãã
ããC++ã® ç°è¨èªéã¤ã³ã¿ãã§ã¼ã¹ FFIã使ãã°ãObjectibe-CãSwiftãã C++ãéã㦠Rustãå®è¡åºæ¥ã¾ã
ãã®ããã®ç°å¢æ§ç¯
ã¨ãããã xcodeã§ã®ãã«ããè¡ã
Rustã®ã¤ã³ã¹ãã¼ã«
Rustèªä½ã¯ ããã±ã¼ã¸ããã¼ã¸ã£ããåºæ¥ããããã®å ´åã 㨠Rustã®ãã¼ã¸ã§ã³ç®¡çãªã©ãä¸ä¾¿ãªã®ã§
ããã¤ã³ã¹ãã¼ã«ãã¦ããå ´åã¯ãä¸æ¦åé¤ããRustupãã¤ã³ã¹ãã¼ã«ãã
ç°å¢æ§ç¯ã¯ä¸è¨åç
§
Building and Deploying a Rust library on iOS
æ¸ãã¦ãéãå®è¡ããã°åºæ¥ããã©ä¸å¿ç°¡åã«
xcode build toolã®ã¤ã³ã¹ãã¼ã«
xcode-select --install
ã«ã¦ãxcodeã®ã¤ã³ã¹ãã¼ã«
rustupã®ã¤ã³ã¹ãã¼ã«
curl https://sh.rustup.rs -sSf | sh
rustupãã¤ã³ã¹ãã¼ã«ãã
iosãiosã·ãã¥ã¬ã¼ã¿ç¨ã®ToolChainã®ã¤ã³ã¹ãã¼ã«
rustup target add aarch64-apple-ios armv7-apple-ios armv7s-apple-ios x86_64-apple-ios i386-apple-ios
iosã ãã§ãªããiosã·ãã¥ã¬ã¼ã¿ãå ¥ãã¦ããã¨éçºã楽
Cargoã®ã¤ã³ã¹ãã¼ã«
cargo install cargo-lipo
ããã±ã¼ã¸ããã¼ã¸ã£ï¼ãã«ããã¼ã«ã®Cargoã¯æ¯éå ¥ãã¦ããã¹ãã
ç°å¢å¤æ°
bash_profile çã« cargoã®ãã¹ã®è¨å®ãå ¥ãã®ã§ãsourceãã¦ç°å¢å¤æ°ãèªã¿è¾¼ã¿ç´ã
source ~/.bash_profile
ãµã³ãã«
ããã¾ããä¸è¨URLã®ã¨ããã«ããã°ãã
Rustãã¡ã¤ã«ä½æ
lib.rs
use std::os::raw::{c_char}; use std::ffi::{CString, CStr}; #[no_mangle] pub extern fn rust_greeting(to: *const c_char) -> *mut c_char { let c_str = unsafe { CStr::from_ptr(to) }; let recipient = match c_str.to_str() { Err(_) => "there", Ok(string) => string, }; CString::new("Hello ".to_owned() + recipient).unwrap().into_raw() } #[no_mangle] pub extern fn rust_greeting_free(s: *mut c_char) { unsafe { if s.is_null() { return } CString::from_raw(s) }; }
Rustã®ææ³ã¯ä»åã¯çç¥
rust_greetingé¢æ°ã¯ å¼æ°ã«æååãåãåã "Hello " ãé ã«ã¤ãã¦è¿ã
rust_greeting_free㯠ä½æããæååãéæ¾ãã
FFIç¨ããã
greetings.h
#include <stdint.h> const char* rust_greeting(const char* to); void rust_greeting_free(char *);
ä¸è¨ã®Rusté¢æ°ãå¼ã³åºãããã®ãããã§ãã
toml
Rustã®ãã«ãã®ããããæããªããã°ãªããªã
Cargo.toml
[package] name = "greetings" version = "0.1.1" authors = ["fluffyemily <[email protected]>"] description = "Example static library project built for iOS" publish = false [lib] name = "greetings" crate-type = ["staticlib", "cdylib"]
ä»åã¯ãã©ã¤ãã©ãªãä½æããã®ã§ãcreate-type㯠ã¹ã¿ãã£ãã¯ã©ã¤ãã©ãªã¨ãã¤ãããã¯ã©ã¤ãã©ãªãæå®ãã
rustã®ãã«ã
cargo lipo --release
lipoã使ãã¨ä¾¿å©ã§ãã
ä»ã¯ToolChainã« iOSé¢é£ãããã¦ããã®ã§ããããããã«ãããã
ã¾ããUniversalã©ã¤ãã©ãªã¨ãããå
¨ã¦ã®ToolChainã®ã©ã¤ãã©ãªãã¾ã¨ã¾ã£ããã®ãä½æãããã®ã§
ãããæå®ããã°ãã¨ãã¥ã¬ã¼ã¿ã§ãå®æ©ã§ãã32bitã§ã64bitã§ããè¨å®å¤æ´ä¸è¦ã§ä¾¿å©ã
xcodeã§ããã¸ã§ã¯ãä½æ
ã¨ããããSinglePageããã¸ã§ã¯ããä½æã
å
ç¨ã®ä½æãããUniversalã©ã¤ãã©ãªã¨ãlibresolvããªã³ã¯ãã
ã¾ãããªã³ã¯ãã¹ã« Universalã®å ´æãæå®ãã
Swift Bridgeãã¡ã¤ã«
RustããC++ã¸ã®ããªãã¸ã¯ ä¸è¨ ã©ã¤ãã©ãªä½æã§C++ã¨ã¢ã¯ã»ã¹å¯è½ã
Objective-Cã¯C++ã¨äºææ§ããã ãã®ã¾ã¾å®è¡ã§ãã
Swiftã¨C++ãç¸äºå¼ã³åºãããããã« Bridgeãä½ã
#ifndef Greetings_Bridging_Header_h #define Greetings_Bridging_Header_h #import "greetings.h" #endif
ãã®ãgreetings.hã¯ãå
ç¨ä½ã£ã Rusté¢æ°ã®Cè¨èªãããã§ãã
importã§æãããã¨æããããããã®SearchPathã追å ããã°è¯ã
Swiftã³ã¼ãä½æ
RustGreetings.swift
class RustGreetings { func sayHello(to: String) -> String { let result = rust_greeting(to) let swift_result = String(cString: result!) rust_greeting_free(UnsafeMutablePointer(mutating: result)) return swift_result } }
Rustã®Bridgeãããé¢æ° rust_greetingãrust_greeting_freeããå¼ã³åºãWrapã¯ã©ã¹
å¤å°é¢åã ãããããã£ã¦å¼ã³åºããã¨ãåºæ¥ã
ãããå®è¡ããããã« ViewControllerã® viewDidLoadedã« ä¸è¨ãå¼ã³åºãã³ã¼ããæ¸ã
let rustGreetings = RustGreetings() print("\(rustGreetings.sayHello(to: "world"))")
å®è¡
å®è¡ãã㨠Hello Worldãã¨ã³ã³ã½ã¼ã«ã«åºãã¯ãã