Rust移动开发:Rust在iOS端集成使用介绍

iOS调用Rust

  • 上篇介绍了 Rust移动开发:Rust在Android端集成使用介绍, 这篇主要看下iOS上如何使用Rust,Rust可以给移动端开发提供跨平台,通用组件支持。

  • 该篇适合对iOS、Rust了解,想知道如何整合调用和编译的,如果想要工程源码,可以评论或留言有解疑也可进行询问(更多最新文章也可关注微信公号: 良技漫谈)

一,开发环境:

  • 确保xcode开发环境,推荐官方文档, 安装即可

  • rust开发环境

  • xcode及iOS调试设备

二,添加rust交叉编译

  • 同android一样,可以添加支持ios的编译

    rustup target add aarch64-apple-ios x86_64-apple-ios

  • 初始化 cargo-lipo : 这个create可以编译rs为iOS需要的库

    cargo install cargo-lipo

三,创建工程

  • 这里的rs代码直接 (参考了mozilla的例子,只为测试验证集成过程)

  • 创建iOS基本工程,并创建rust的库工程,可以创建lib,也可以直接rs工程。 (一套rust代码,提供多个平台,那一般可以创建lib库,这样rust工程来调试后,统一对外提供lib库代码,由lib库代码编译对应的so,或者.a文件)

    cargo new Rust_iOS --lib

  • 这里使用 Rust_iOS 作为为iOS工程提供的rust 库代码,通过 cargo-lipo 编译出.a的库文件,为ios工程进行调用。

rust代码添加

  • 在lib.rs里添加下边代码

    use std::ffi::{CStr, CString};
    use std::os::raw::c_char;

    //#[no_mangle] 告诉编译器不要破坏函数名,确保函数名称被导入到 C 文件
    //extern 告诉 Rust 编译器方法将要在 Rust 以外的地方调用,要确保其按照 C 的调用规则编译。
    #[no_mangle]
    pub extern "C" 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 "C" fn rust_greeting_free(s: *mut c_char) {
    unsafe {
    if s.is_null() {
    return;
    }
    CString::from_raw(s)
    };
    }

  • • **greetings.h :**src下添加一个名为 greetings.h 的新文件,来定义一下 C 接口,iOS调用的Rust函数在这里定义

    #include <stdint.h>
    const char* rust_greeting(const char* to);
    void rust_greeting_free(char *);

  • Cargo.toml定义编译类型: staticlib 编译会生成 .a 文件(在 Linux 和 MacOS 上),或 .lib 文件(在 Windows 上)。

    [lib]
    name = "greetings"
    crate-type = ["staticlib", "cdylib"]

  • 编译成静态库:

    cargo lipo --release

构建产物位置在 target/下,通用 iOS 库的位置在 /target/universal/release/libRust_iOS.a

四,iOS工程引入Rust库:

导入 libRust_iOS.a 库:

  • 创建demo ios 工程, 导入 libRust_iOS.a 库(从rust工程找到,直接拖进入工程target下general)

  • 链接 libresolv.tbd。点击 Linked Frameworks 列表底部的 + 并在搜索框中键入 libresolv。选择 libresolv.tbd

bridging header创建:

  • 创建之前先把之前定义在rust工程里的.h文件引入过来,这个.h文件是rust代码调用的声明入口(File\Add files to"iOSIntegratingRust" )

  • 创建bridging header: File\New\File..。从提供的选项中选择 iOS Source Header File 并选择 Next。将文件命名为 Greetings-Bridging-Header.h 并选择 Create

  • 引入greetings.h

    #ifndef Greetings_Bridging_Header_h
    #define Greetings_Bridging_Header_h
    #import "greetings.h"
    #endif

iOS Build Settings:

  • 设置Objective-C Bridging Header链接要的.h文件, 工程 target 里打开 Build Settings 选项卡。将 Objective-C Bridging Header设置为$(PROJECT_DIR)/Greetings-Bridging-Header.h (要看自己.h所在的位置)

  • 设置 Xcode 要链接 Rust 库的路径, Build Settings 中 Library Search Paths中设置 $(PROJECT_DIR)/../Rust_iOS/target/universal/release (要看自己库实际位置)

五,iOS代码调用:

  • 从刚demo工程里新建一个 swift 文件,命名为 RustGreetings

    import Foundation
    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
    }
    }

  • ViewController.swift里 添加代码验证调用

    复制代码
      override func viewDidLoad() {
          super.viewDidLoad()
          // Do any additional setup after loading the view.
          let rustGreetings = RustGreetings()
          print("\(rustGreetings.sayHello(to: "world"))")
      }

PS: 也欢迎大家评论和交流~ 更多文章也可关注微信公号:良技漫谈

相关推荐
程序员爱钓鱼5 分钟前
Rust 泛型 Generics详解:编写可复用且类型安全的代码
后端·面试·rust
小满zs13 分钟前
Go语言第九章(错误处理)
后端·go
桦说编程13 分钟前
深入理解 FutureTask 状态机——从契约到实现
java·后端·性能优化
程序员爱钓鱼16 分钟前
Go 编程实战:指针 Pointer——理解地址、取址与解引用
后端·面试·go
To_OC9 小时前
从一行入口代码啃透 NestJS:工厂模式、装饰器和依赖注入是怎么串起来的
后端·设计模式·nestjs
Python私教9 小时前
多个项目怎么安全合并?先适配,再切换
后端·python·架构
Python私教10 小时前
从表格到管理系统:别先写页面,先补齐权限、流程和审计
数据库·后端·架构
北斗落凡尘11 小时前
LangGraph 入门实战(12)--使用MCP
后端·python·langchain
SomeB1oody13 小时前
【RustyML入门】6.0. 数学工具
开发语言·后端·机器学习·rust·教程
IT_陈寒13 小时前
为什么我的JavaScript闭包总是漏掉那个变量?
前端·人工智能·后端