rust工程

文章目录

  • Cargo
  • macOS配置rust环境
    • vscode配置
  • 目录结构
    • Cargo.toml
    • cargo命令
    • hello world
  • 跟web交互
    • WebAssembly
  • 跟Android交互
    • 配置Android环境
    • JNI例子
    • NDK例子

Rust 是一种现代的、系统级的编程语言,它强调并发安全、内存安全和高性能。Rust 的设计目标是提供一种有着良好抽象能力,同时又能够保证代码运行效率和安全性的语言。它将内存安全、并发安全和数据竞争检测等特性作为语言的一部分,通过所有权系统、借用检查器和生命周期等机制来防止常见的编程错误。

下面是一些与 Rust 相关的工具和库的介绍:

  1. Cargo
    Cargo 是 Rust 的包管理工具和构建系统。它能够自动管理 Rust 项目的依赖关系,并提供命令行工具来构建、测试和运行项目。Cargo 简化了 Rust 项目的创建和管理过程,使得开发者可以更专注于编写代码而不用过多关注构建细节。

  2. Clippy
    Clippy 是 Rust 的静态代码分析工具,它能够检测出一些潜在的代码问题和不良习惯,并给出相应的建议。Clippy 可以帮助开发者编写更规范、更高质量的 Rust 代码。

  3. Rust 文档(Rust Docs)
    Rust Docs 是 Rust 官方提供的文档工具,用于生成和浏览 Rust 标准库和第三方库的文档。它为 Rust 开发者提供了一个方便的方式来查阅和学习 Rust 相关的文档。

  4. Rust 标准库(Rust Standard Library)
    Rust 标准库是 Rust 语言的核心库,它提供了许多常用的数据结构、算法和系统调用等功能。开发者可以直接使用标准库中的类型和函数,以快速构建高效、安全的 Rust 程序。

  5. Rust 编译器(rustc)
    Rust 编译器是将 Rust 代码编译为可执行文件或库的工具。它负责解析、类型检查、代码生成等编译过程,并生成适应目标平台的机器码。Rust 编译器是 Rust 语言的核心组件之一,它实现了 Rust 语言规范,并负责将 Rust 代码转化为可执行的程序。

这些工具和库都是 Rust 生态系统中重要的组成部分,它们与 Rust 的设计理念和目标相辅相成,使得开发者能够更加高效地编写、测试和维护 Rust 项目。无论是初学者还是有经验的开发者,对于这些工具的了解和使用都能够提升开发效率和代码质量。

Cargo

Cargo 是 Rust 的官方构建工具和包管理器。它用于帮助开发者构建、测试和管理 Rust 项目,简化了项目的依赖管理、构建配置和发布流程。下面详细介绍一下 Cargo 的主要功能和用法:

  1. 创建项目: 使用 Cargo 可以快速创建一个新的 Rust 项目。通过运行 cargo new <project_name> 命令,在当前目录下生成一个新的项目文件夹,并自动生成了一个简单的目录结构和必要的文件,包括 Cargo.tomlsrc/main.rs 等。

  2. 依赖管理: Cargo 管理 Rust 项目的依赖关系。在项目的 Cargo.toml 文件中,可以指定项目所需要的外部依赖库及其版本。当构建项目时,Cargo 会自动下载并编译这些依赖库,并将其集成到项目中。可以使用 cargo build 命令来构建项目并处理依赖关系。

  3. 构建项目: Cargo 提供了简洁的命令行接口,可以用于构建 Rust 项目。运行 cargo build 命令将会编译项目的源代码,并生成可执行文件或库文件。Cargo 会根据项目的依赖关系自动解析和编译相关的代码。

  4. 运行项目: 使用 cargo run 命令可以方便地运行 Rust 项目。Cargo 会自动编译项目并执行生成的可执行文件。如果项目是一个库,可以使用 cargo test 命令来运行项目中的测试用例。

  5. 测试项目: Cargo 提供了内置的测试框架和命令,用于编写和运行测试用例。在项目中的 src 目录下创建一个名为 tests 的子目录,并在其中编写测试用例。然后使用 cargo test 命令运行测试,并查看测试结果。

  6. 发布项目: 使用 Cargo 可以方便地发布 Rust 项目。通过运行 cargo build --release 命令,Cargo 会进行优化编译,生成一个发布版本的可执行文件。然后可以将生成的可执行文件部署到生产环境中。

  7. 文档生成: Cargo 提供了文档生成工具,可以生成项目的文档。在项目中的注释中添加文档注解,并使用 cargo doc 命令生成文档。生成的文档会包含项目的结构、函数、模块等信息,并可以通过浏览器进行查看。

  8. 更新依赖: 当项目依赖的库有新的版本发布时,可以使用 Cargo 更新依赖关系。运行 cargo update 命令,Cargo 会检查项目的依赖关系,并下载最新的版本。

除了上述功能,Cargo 还提供了其他一些辅助功能,例如初始化 Git 仓库、自动下载编译工具链(Rustup)、发布到 Cargo 社区等。这些功能使得 Cargo 成为 Rust 开发中必不可少的工具,极大地简化了项目的管理和构建过程,提高了开发效率。

macOS配置rust环境

在 macOS 上配置 Rust 环境,可以按照以下步骤进行:

  1. 安装 Homebrew(如果未安装):
    打开终端,并执行以下命令来安装 Homebrew:

    /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
    
  2. 安装 Rust 编程语言:
    在终端中执行以下命令来安装 Rust:

    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
    

    这将下载并运行 Rust 安装脚本。

  3. 配置环境变量:
    安装完成后,脚本会提示你将 Rust 相关的可执行文件路径添加到环境变量中。请按照提示选择「2」或输入「2」,然后按 Enter 键。

  4. 初始化 Rust 环境:
    执行以下命令初始化 Rust 环境:

    source $HOME/.cargo/env
    
  5. 验证安装:
    在终端中执行以下命令验证 Rust 是否成功安装:

    rustc --version
    cargo --version
    
  6. 安装 wasm-pack:
    这将下载并执行 wasm-pack 安装脚本。根据提示,可能需要输入管理员密码来完成安装。

    curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
    wasm-pack --version
    

如果以上步骤没有出现任何错误,那么你的 macOS 系统上已成功配置了 Rust 环境。你可以开始使用 Rust 编程语言进行开发了。需要注意的是,Rust 包管理器 Cargo 也已经安装好了,它可以帮助你管理 Rust 项目的依赖和构建过程。

希望上述步骤能够帮助到你顺利配置 Rust 环境。如果在安装过程中遇到任何问题,你可以参考 Rust 官方文档 或 Rust 社区中的相关资源来获取更多帮助。

vscode配置

当在 VS Code 中配置 Rust 开发环境时,以下是几个常用的插件推荐:

  1. rust-analyzer:这是官方提供的 Rust 插件,是一个功能强大的 Rust 语言服务器,它提供了智能代码补全、重构建议、错误检查等高级功能。

  2. Crates by serayuzgur:这个插件提供了对 Cargo.toml 和 Cargo.lock 文件的支持,可以方便地查看和管理项目的依赖关系。

  3. CodeLLDB by Vadim Chugunov:如果你需要在 VS Code 中进行 Rust 代码的调试,这个插件可以与 LLDB 调试器集成,提供了强大的调试功能。

  4. Better TOML by bungcip:这个插件提供了对 TOML 文件的语法高亮和格式化支持,对于编辑 Cargo.toml 文件来说非常实用。

  5. Rusty Code by matklad:Rusty Code 插件提供了代码格式化、自动导入缺失的模块、错误检查等功能,帮助减少开发中的一些常见错误。

以上这些插件可以为你提供更好的 Rust 开发体验,使得在 VS Code 中编写、调试和管理 Rust 项目更加便捷和高效。可以通过在 VS Code 中搜索插件名称并安装来开始配置 Rust 开发环境。同时,也可以根据自己的需求和喜好,探索其他的 Rust 插件。

目录结构

Rust 项目通常遵循一种常见的目录结构,该结构有助于组织代码、资源文件和构建工具。以下是一个常见的 Rust 项目目录结构示例:

myproject/├── src/│   └── main.rs├── Cargo.toml└── Cargo.lock

让我们逐个解释每个目录和文件的作用:

  • src/:这是存放 Rust 源代码的目录。你可以在此目录下创建多个 .rs 文件来组织你的代码。通常,你会在 src/ 目录下创建一个 main.rs 文件,其中包含项目的入口点。

  • main.rs:这是包含项目入口点(例如 main 函数)的 Rust 源代码文件。它是 Rust 程序的起点,负责启动应用程序的执行流程。

  • Cargo.toml:这是 Rust 项目的配置文件,使用 Toml 格式来描述项目的依赖项、构建选项和其他元数据。你可以在 Cargo.toml 中指定项目名称、版本号、作者信息等。

  • Cargo.lock:这是由 Cargo 自动生成的锁定文件。它记录了实际使用的依赖项及其确切版本,以确保在后续构建中使用相同的依赖项版本。

除了上述基本结构之外,Rust 项目通常还包括其他目录和文件:

  • tests/:如果你的项目包含测试代码,通常会在此目录下创建测试文件。测试代码用于验证项目中各个部分的正确性。

  • examples/:如果你想提供一些示例用法或演示代码,可以将其放置在此目录下。

  • target/:这是 Cargo 自动生成的目录,在构建过程中存储目标文件和编译生成的二进制可执行文件。

  • build.rs:这是一个可选的构建脚本文件,使用 Rust 代码编写。它允许你在构建过程中自定义一些操作,例如生成代码、配置构建选项等。

  • 其他自定义目录:根据项目的需要,你可能还会创建其他自定义的目录,用于存放静态资源文件、模板文件、配置文件等。

请注意,Rust 的目录结构没有强制要求,你可以根据项目的需求进行调整和扩展。上述目录结构只是一个常见的约定,大多数 Rust 项目都遵循类似的结构来提供一致性和易于理解的代码组织方式。

Cargo.toml

Cargo.toml 是 Rust 项目的配置文件,用于指定项目的元数据、依赖项和构建选项。它使用 Toml 格式(Tom’s Obvious, Minimal Language)编写,是一种易于理解和编辑的简单配置语言。要详细了解Cargo请阅读manifest。

下面是一个典型的 Cargo.toml 示例:

[package]
name = "myproject"
version = "0.1.0"
edition = "2021"[dependencies]
crate1 = "1.0"
crate2 = { version = "2.0", features = ["feature1", "feature2"] }[build-dependencies]
build_crate = "1.0"

让我们逐个解释每个部分的含义:

  • [package] 这个部分用于指定项目的元数据信息。

    • name:指定项目的名称。
    • version:指定项目的版本号。
    • edition:指定 Rust 的版本。支持的选项有 "2015""2018""2021"
  • [dependencies] 这个部分用于指定项目的依赖项。你可以列出项目所依赖的外部库或 crate,并指定它们的版本信息。

    • crate1 = "1.0":这表示项目依赖名为 crate1 的 crate,并指定其版本为 1.0
    • crate2 = { version = "2.0", features = ["feature1", "feature2"] }:这表示项目依赖名为 crate2 的 crate,并指定其版本为 2.0,同时启用其中的一些特性。
  • [build-dependencies] 这个部分用于指定项目构建过程中所需要的依赖项。这些依赖项只在构建过程中使用,而不会包含在最终的二进制可执行文件中。

除了上述常见的部分之外,Cargo.toml 文件还支持其他配置选项,如:

  • workspace:用于同时管理多个相关的 Rust 项目。
  • features:用于定义和启用 crate 的不同功能特性。
  • target:用于指定特定的目标平台和相关设置。
  • patch:用于修复或替换依赖项的特定版本。

你可以根据项目的需求自定义 Cargo.toml 文件,添加适当的依赖项、配置选项和元数据信息。Rust 的构建工具 Cargo 将根据 Cargo.toml 中的配置来下载和管理依赖项,并执行相应的构建操作。

希望这个介绍对你有所帮助!如果还有其他问题,请随时提问。

cargo命令

Cargo 是 Rust 的官方构建工具和包管理器,提供了许多命令用于构建、测试、管理和发布 Rust 项目。以下是 Cargo 的常用命令列表:

  1. cargo new:创建一个新的 Rust 项目。

  2. cargo build:构建项目,编译源代码并处理依赖关系。

  3. cargo run:运行项目,编译并执行生成的可执行文件。

  4. cargo test:运行测试用例。

  5. cargo bench:运行基准测试。

  6. cargo doc:生成项目文档。

  7. cargo clean:清理项目构建产生的临时文件和目录。

  8. cargo update:更新项目的依赖库。

  9. cargo init:初始化当前目录为一个 Rust 项目。

  10. cargo check:检查代码是否可以成功编译,但不生成可执行文件。

  11. cargo fix:自动修复一些编译警告和错误。

  12. cargo publish:发布项目到 crates.io,Rust 社区的包管理平台。

  13. cargo install:安装一个二进制包程序到系统路径。

  14. cargo uninstall:卸载一个已安装的二进制包程序。

  15. cargo package:生成一个用于发布的压缩包。

  16. cargo metadata:显示项目的元数据信息,依赖关系等。

  17. cargo fmt:格式化源代码。

  18. cargo clippy:运行 Clippy(Rust 的 lint 工具)对代码进行静态分析。

  19. cargo doc --open:生成文档并在浏览器中打开。

  20. cargo build --release:生成发布版本的可执行文件。

  21. cargo build --target <target>:指定目标平台进行构建。

  22. cargo build --features <features>:启用指定的特性进行构建。

  23. cargo build --no-default-features:禁用默认特性进行构建。

  24. cargo build --all:构建项目及其所有依赖。

  25. cargo build --workspace:在工作区中构建所有子项目。

  26. cargo build --lib:只构建项目中的库文件。

  27. cargo build --bin <name>:只构建指定名称的可执行文件。

  28. cargo build --example <name>:只构建指定名称的示例程序。

  29. cargo build --tests:只构建项目中的测试目标。

  30. cargo build --benches:只构建项目中的基准测试目标。

  31. cargo build --target-dir <dir>:指定构建输出的目录。

  32. cargo build --all-features:启用所有特性进行构建。

  33. cargo build --no-default-runtime:禁用默认运行时(仅适用于编写运行时的 Crate)。

  34. cargo test -- --test-threads=<num>:设置并发运行测试的线程数。

  35. cargo test -- <pattern>:只运行与指定模式匹配的测试。

  36. cargo test -- --ignored:运行被标记为 #[ignore] 的测试。

  37. cargo test --release:以发布模式运行所有测试。

  38. cargo doc --no-deps:生成项目文档,但不包含依赖库的文档。

  39. cargo run -- <args>:在编译并运行项目时传递参数。

  40. cargo check --all-targets:检查项目及其所有目标的代码是否可以成功编译。

  41. cargo fix --edition:自动升级代码到指定的 Rust 版本。

  42. cargo fix --allow-dirty:允许在 Git 工作目录中运行 cargo fix

  43. cargo publish --dry-run:发布前进行 dry-run,检查是否有错误。

  44. cargo publish --allow-dirty:允许在 Git 工作目录中运行 cargo publish

  45. cargo install <crate>:安装指定的 Crate。

  46. cargo install-update <crate>:更新指定的 Crate。

  47. cargo uninstall <crate>:卸载指定的 Crate。

  48. cargo search <query>:在 crates.io 中搜索包。

  49. cargo clean --package <spec>:清理指定的 Package。

  50. cargo metadata --format-version <version>:指定元数据格式的版本。

这些是常用的 Cargo 命令,可以帮助你管理 Rust 项目的构建、测试、文档生成、依赖管理和发布等任务。你可以通过在命令行中输入 cargo --help 来查看更多命令以及它们的详细使用说明。

hello world

要开始你的第一个 Rust “Hello, World!” 项目,按照以下步骤进行:

  1. 安装 Rust 编程语言:首先,确保您已在计算机上安装了 Rust。可以访问 Rust 官方网站,按照指示下载并安装 Rust。

  2. 创建新项目:打开终端或命令提示符,导航到要创建项目的目录,并运行以下命令来创建一个新的 Rust 项目:

    cargo new hello_world
    

    这将在当前目录下创建一个名为 “hello_world” 的新目录,并自动生成一些初始代码。

  3. 进入项目目录:运行以下命令以进入新创建的项目目录:

    cd hello_world
    
  4. 编辑代码:使用你喜欢的文本编辑器打开 src/main.rs 文件,并将以下代码复制粘贴到文件中:

    fn main() {println!("Hello, World!");
    }
    
  5. 构建和运行项目:返回终端或命令提示符,运行以下命令来构建和运行你的项目:

    cargo run
    

    Rust 的构建系统 Cargo 将编译项目并运行生成的可执行文件。你应该会在终端上看到输出 “Hello, World!”。

恭喜!你已经成功创建并运行了你的第一个 Rust “Hello, World!” 项目。从这个简单的示例开始,你可以继续学习和探索 Rust 编程语言的更多方面。

跟web交互

Rust 可以与 Web 进行交互,使你能够构建 Web 应用程序、API 和后端服务。下面是一些可以帮助你在 Rust 中进行 Web 交互的常见方法:

  1. Web 框架:使用 Rust 的 Web 框架可以简化 Web 开发过程,并提供路由、请求处理、中间件等功能。一些流行的 Rust Web 框架包括 Rocket、Actix-web 和 Warp。

  2. HTTP 客户端和服务器:Rust 提供了多个库用于构建 HTTP 客户端和服务器。例如,reqwest 是一个常用的 HTTP 客户端库,hyper 是一个强大的 HTTP 服务器库。

  3. 数据库访问:与 Web 相关的应用程序通常需要与数据库进行交互。Rust 提供了各种数据库连接库和 ORM(对象关系映射)工具,例如 Diesel、sqlx 和 rusqlite。

  4. 模板引擎:用于生成动态 HTML 页面的模板引擎在 Web 开发中非常有用。Rust 中一些流行的模板引擎包括 Tera 和 Handlebars。

  5. WebAssembly(Wasm):Rust 具备编写 WebAssembly 模块的能力,这使得你可以在 Web 浏览器中运行原生速度的 Rust 代码。你可以使用 wasm-bindgen 和 wasm-pack 工具来构建和集成 Rust 和 JavaScript 之间的接口。

  6. WebSocket:Rust 提供了用于 WebSocket 通信的库,如 tokio-tungstenite 和 actix-web 的 WebSocket 功能。

以上只是一些在 Rust 中进行 Web 交互的方法示例,你可以根据具体需求选择合适的库和工具。Rust 社区拥有丰富的资源和文档,可以帮助你深入了解和学习 Rust 的 Web 开发。

WebAssembly

以下是一个使用 Rust 和 WebAssembly(Wasm)进行交互的示例:

首先,确保你已经安装了 Rust 和 wasm-pack 工具。

  1. 创建新的 Rust 项目:
    打开终端或命令提示符,导航到要创建项目的目录,并运行以下命令来创建一个新的 Rust 项目:

    cargo new wasm_example
    cd wasm_example
    
  2. 添加依赖:
    在项目的根目录中,打开 Cargo.toml 文件,并添加以下代码来添加 wasm-bindgen 和 js-sys 的依赖:

    [lib]
    crate-type = ["cdylib"][dependencies]
    wasm-bindgen = "0.2"
    js-sys = "0.3"
    
  3. 编写 Rust 代码:
    打开 src/lib.rs 文件,并使用以下代码替换其中的内容:

    use wasm_bindgen::prelude::*;#[wasm_bindgen]
    extern "C" {#[wasm_bindgen(js_namespace = console)]fn log(s: &str);
    }#[wasm_bindgen]
    pub fn greet(name: &str) {let message = format!("FromRust, {}!", name);log(&message);
    }
    

    上述代码定义了一个 greet 函数,它接受一个字符串参数,并在控制台输出问候消息。

  4. 生成 Wasm 模块:
    在终端中运行以下命令来生成 Wasm 模块:

    wasm-pack build --target web
    

    这将使用 wasm-pack 工具将 Rust 代码编译为 WebAssembly 模块,并生成与 JavaScript 交互的必要代码。

  5. 创建 HTML 文件:
    在项目的根目录中,创建一个名为 index.html 的文件,并使用以下代码填充它:

    <!DOCTYPE html>
    <html lang="en">
    <head><meta charset="UTF-8"><title>WebAssembly Example</title><script type="module">import init, { greet } from './pkg/wasm_example.js';async function run() {await init();greet("Alice");}run();</script>
    </head>
    <body>
    </body>
    </html>
    

    上述代码导入了生成的 wasm_example.js 文件,并在页面加载完成后调用 greet 函数。

  6. 启动本地服务器:
    在终端中运行以下命令来启动一个简单的本地服务器:

    python -m http.server
    
  7. 运行示例:
    打开浏览器并访问 http://localhost:8000,然后打开浏览器的控制台。你应该会看到控制台输出了 “Hello, Alice!”。

通过上述步骤,你可以在 Rust 中创建一个简单的 WebAssembly 模块,并与 JavaScript 进行交互。你可以根据需要扩展这个示例,并使用更多的 Rust 函数与 JavaScript 进行交互。

跟Android交互

当你想要在 Android 平台上使用 Rust 与 Java 进行交互时,下面是一些具体的步骤和工具可以帮助你实现这一目标:

  1. 使用 JNI(Java Native Interface):JNI 提供了一种方式,使得 Java 和本地代码能够进行交互。你可以使用 Rust 编写本地代码,并通过 JNI 接口与 Android 的 Java 代码进行通信。为了在 Rust 中与 JNI 交互,你可以使用 jnirust-jni 等库来编写相应的绑定代码。

    需要完成的步骤:

    • 编写 Rust 的绑定代码,将 Rust 函数暴露给 JNI。
    • 生成动态链接库(.so 文件)。
    • 在 Android 项目中使用 JNI 接口调用 Rust 函数。
  2. 使用 NDK(Native Development Kit):NDK 允许你使用 C、C++ 或其他本地语言来开发 Android 应用程序。你可以使用 Rust 作为 C 或 C++ 的替代语言,并在 NDK 中构建包含 Rust 代码的本地库。然后,你可以使用 Java 代码通过 JNI 调用这些本地库。

    需要完成的步骤:

    • 创建 Android NDK 项目,并配置好 Rust 的构建环境。
    • 编写 Rust 代码并构建共享库(.so 文件)。
    • 使用 JNI 接口在 Java 代码中调用本地库中的函数。
  3. 使用 FFI(Foreign Function Interface):FFI 允许不同语言之间进行函数调用和数据传递。你可以使用 Rust 的 FFI 功能,将 Rust 函数暴露给其他语言,比如 Java。通过这种方式,你可以在 Android 的 Java 代码中直接调用 Rust 函数。

    需要完成的步骤:

    • 使用 Rust 的 #[no_mangle]extern 关键字将函数标记为可供外部调用。
    • 根据 FFI 规范编写 Java 代码来调用 Rust 函数。
    • 在 Android 项目中将 Rust 代码和 Java 代码一起编译和构建。
  4. 使用 rust-android-gradle 插件:rust-android-gradle 是一个方便的工具,可用于将 Rust 代码集成到 Android 项目中。它可以自动处理 Rust 代码的构建和链接,并与 Gradle 构建系统集成。

    需要完成的步骤:

    • 在 Android 项目的 Gradle 文件中添加 rust-android-gradle 插件的依赖。
    • 创建 Rust 模块并设置构建配置。
    • 在 Android 项目中使用预生成的 Rust 库。

请注意,在实施任何方法之前,你需要确保已经按照相应工具和库的文档进行了正确的配置和设置。每种方法都有其优势和适用场景,因此根据需求选择最适合你的方法。

希望这些详细的步骤能够帮助你更好地理解 Rust 与 Android 的交互,并实现你的项目需求。

配置Android环境

要正确安装和配置 Android NDK,请按照以下步骤进行操作:

  1. 下载 Android NDK:访问 Android NDK 的官方网站下载适合你操作系统的最新版本。

  2. 解压缩文件:将下载的 NDK 压缩文件解压到你选择的位置。例如,你可以将其解压到 ~/android-ndk 目录下。

  3. 配置环境变量:打开终端并编辑你的 shell 配置文件(例如 ~/.bashrc~/.zshrc)。在文件末尾添加以下行(假设你将 NDK 解压缩到了 ~/android-ndk 目录):

    export ANDROID_NDK_HOME=~/android-ndk
    export PATH=$PATH:$ANDROID_NDK_HOME
    

    保存文件后执行以下命令使配置立即生效:

    source ~/.bashrc
    

    或者你也可以重新启动终端。

  4. 测试安装:在终端中运行以下命令验证是否正确安装和配置了 Android NDK:

    ndk-build --version
    

    如果成功安装并配置,将显示 NDK 版本信息。

  5. 安装交叉编译目标:运行以下命令来安装 aarch64-linux-android 目标:

    rustup target add aarch64-linux-android
    rustup target add arm-linux-androideabi
    rustup target add armv7-linux-androideabi
    rustup target add i686-linux-android
    rustup target add thumbv7neon-linux-androideabi
    rustup target add x86_64-linux-android
    
  6. 配置链接器和编译参数:创建一个名为 $HOME/.cargo 的文件夹,并在其中创建一个名为 config 的文件。在 config 文件中添加以下内容:

    [target.arm-linux-androideabi]
    ar = "llvm-ar"
    linker = "armv7a-linux-androideabi29-clang"[target.armv7-linux-androideabi]
    ar = "llvm-ar"
    linker = "armv7a-linux-androideabi29-clang"[target.thumbv7neon-linux-androideabi]
    ar = "llvm-ar"
    linker = "armv7a-linux-androideabi29-clang"[target.aarch64-linux-android]
    ar = "llvm-ar"
    linker = "aarch64-linux-android29-clang"[target.i686-linux-android]
    ar = "llvm-ar"
    linker = "i686-linux-android29-clang"[target.x86_64-linux-android]
    ar = "llvm-ar"
    linker = "x86_64-linux-android29-clang"
    
  7. 测试编译:现在,你可以尝试使用 Cargo 构建你的项目,并将目标设置为 Android 平台,例如:

    cargo build --target aarch64-linux-android
    

通过按照以上步骤配置 Rust 的交叉编译环境,你应该能够开始在 Android 平台上使用 Rust 进行交叉编译了。

JNI例子

当使用 JNI 实现 Rust 与 Android 的交互时,可以使用以下示例来说明具体步骤。假设你希望在 Android 应用程序中调用一个计算两个整数和的 Rust 函数。

  1. 创建一个名为 rust_lib 的 Rust 项目cargo new rust_lib --lib,并添加以下内容到 lib.rs 文件中:

    #[no_mangle]
    pub extern "C" fn rust_greet(name: *const c_char) -> *mut c_char {let c_str = unsafe {assert!(!name.is_null());CStr::from_ptr(name)};let name = c_str.to_str().unwrap();let greeting = format!("FromRust, {}!", name);CString::new(greeting).unwrap().into_raw()
    }
    
  2. Cargo.toml 文件中添加以下内容:

    [lib]
    crate-type = ["cdylib"]
    
  3. 使用以下命令在 Rust 中构建共享库文件:

    cargo build --target aarch64-linux-android
    

    上述命令将在 target/aarch64-linux-android/debug/librust_lib.so 中生成共享库文件。

  4. 在 Android 项目中的 app 模块下的 src/main 目录中创建一个名为 jni 的文件夹,并在其中创建一个 native-lib.cpp 文件。

  5. native-lib.cpp 文件中添加以下内容:

    #include <jni.h>
    #include <string>
    #include <dlfcn.h>extern "C" JNIEXPORT jstring JNICALL
    Java_com_example_androidapp_MainActivity_stringFromJNI(JNIEnv* env,jobject /* this */,jstring name) {const char* nativeString = env->GetStringUTFChars(name, nullptr);void* handle = dlopen("librust_lib.so", RTLD_LAZY);if (!handle) {return env->NewStringUTF("Failed to load Rust library");}typedef char* (*rust_greet_func)(const char*);rust_greet_func greet = (rust_greet_func)dlsym(handle, "rust_greet");if (!greet) {return env->NewStringUTF("Failed to find Rust function");}char* result = greet(nativeString);env->ReleaseStringUTFChars(name, nativeString);jstring output = env->NewStringUTF(result);free(result);dlclose(handle);return output;
    }
    

    要把librust_lib.so复制到jniLibs对应的目录中。

  6. 配置cmake

    app build.gradle

    android {// ...defaultConfig {// ...externalNativeBuild {cmake {cppFlags '-std=c++17'}}ndk {abiFilters "arm64-v8a"}}sourceSets {main {// 配置 jniLibs 文件目录jniLibs.srcDirs = ['libs']}}externalNativeBuild {cmake {path file('src/main/cpp/CMakeLists.txt')version '3.22.1'}}
    }
    

    CMakeLists.txt

    cmake_minimum_required(VERSION 3.22.1)
    project("rust_jni")
    add_library(${CMAKE_PROJECT_NAME} SHARED native-lib.cpp)
    target_link_libraries(${CMAKE_PROJECT_NAME} android log)
    
  7. 在 Android 项目的 Java 类中,添加以下方法:

    public class MainActivity extends AppCompatActivity {static {System.loadLibrary("native-lib");}public native String stringFromJNI(String name);// ...
    }
    
  8. MainActivity.java 中的任何适当的方法中调用 stringFromJNI() 方法,并向其传递一个字符串参数:

    String greeting = stringFromJNI("Stone " + new Date().toString());
    Log.d("MainActivity", greeting);
    

这样,在 Android 应用程序中运行时,将调用 Rust 函数并输出日志中的问候语。

NDK例子

当使用 Rust 和 Android NDK 进行开发时,以下是一个详细的示例,展示如何在 Android 项目中使用 Rust 编写并调用函数。

  1. 创建 Rust 项目:

    在终端中执行以下命令,创建一个名为 rust-ndk 的 Rust 项目:

    cargo new rust-ndk
    

    进入项目目录:

    cd rust-ndk
    
  2. 添加依赖项:

    打开项目中的 Cargo.toml 文件,并添加 ndkjnilibc 作为依赖项:

    [lib]
    crate-type = ["cdylib"]
    path = "src/jni.rs"[dependencies]
    jni = "0.21.1"
    
  3. 创建 JNI 接口:

    在项目的根目录下创建一个名为 jni.rs 的文件,并添加以下代码:

    use jni::JNIEnv;
    use jni::objects::{JClass, JString};
    use jni::sys::jstring;#[no_mangle]
    pub unsafe extern "C" fn Java_com_example_rustndk_MainActivity_stringFromRust<'local>(mut env: JNIEnv<'local>,_: JClass<'local>,input: JString<'local>)-> jstring {let input: String = env.get_string(&input).expect("Couldn't get java string!").into();let output = env.new_string(format!("FromRust, {}!", input)).expect("Couldn't create java string!");output.into_raw()
    }
    

    这个例子中的 Java_com_example_rustndk_MainActivity_stringFromRust 函数是一个 JNI 方法,在字符串前面拼接一个FromRust字符串。

  4. 构建 Rust 项目:

    在终端中执行以下命令构建 Rust 项目:

    cargo build --target aarch64-linux-android --release
    
  5. 创建 Android 项目:

    使用 Android Studio 创建一个新的 Android 项目,并导航到 app/src/main 目录。

  6. 添加 Rust 动态链接库:

    将生成的 .so 文件复制到 app/src/main/jniLibs 目录下(如果没有该目录则自行创建)。例如,将 ../rust-ndk/target/release/librust_ndk.so 文件复制到 app/src/main/jniLibs/arm64-v8a/ 目录下。

  7. 创建 Java 类和 JNI 接口:

    app/src/main/java/com/example/rustndk 目录下创建一个名为 MainActivity.java 的类,并添加以下代码:

    package com.example.rustndk;public class MainActivity extends AppCompatActivity {static {System.loadLibrary("rust_ndk");}private ActivityMainBinding binding;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);binding = ActivityMainBinding.inflate(getLayoutInflater());setContentView(binding.getRoot());// Example of a call to a native methodTextView tv = binding.sampleText;tv.setText(stringFromRust("Stone " + new Date().toString()));}public native String stringFromRust(String str);
    }
    

    这个类包含了一个静态代码块,用于加载名为 rust_ndk 的动态链接库。还有一个名为 stringFromRust 的方法,用于调用 Rust 函数。

这样,在 Android 应用程序中运行时,将调用 Rust 函数并输出日志中的问候语。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/53790.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java中LinkList的基本介绍和细节讨论。双向链表的代码和LinkList的源码。LinkList和ArrayList的比较与选择。

LinkedList 是 Java 中的一个双向链表实现的类&#xff0c;它实现了 List 接口&#xff0c;同时也实现了 Deque 接口&#xff0c;因此可以用作列表、队列或双端队列。下面是关于 LinkedList 的基本介绍和细节讨论&#xff1a; 基本介绍&#xff1a; LinkedList 是一个双向链表…

keepalived+haproxy 搭建高可用高负载高性能rabbitmq集群

一、环境准备 1. 我这里准备了三台centos7 虚拟机 主机名主机地址软件node-01192.168.157.133rabbitmq、erlang、haproxy、keepalivednode-02192.168.157.134rabbitmq、erlang、haproxy、keepalivednode-03192.168.157.135rabbitmq、erlang 2. 关闭三台机器的防火墙 # 关闭…

合并两个链表

题目描述 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 比如以下例子&#xff1a; 题目接口&#xff1a; /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListN…

SQL阶段性优化

&#x1f61c;作 者&#xff1a;是江迪呀✒️本文关键词&#xff1a;MySQL、SQL优化、阶段性优化☀️每日 一言&#xff1a;我们要把懦弱扼杀在摇篮中。 一、前言 我们在做系统的过程中&#xff0c;难免会遇到页面查询速度慢&#xff0c;性能差的问题&#xff0c;…

mysql57、mysql80 目录结构 之 Windows

查看mysql 数据存储的位置 /bin&#xff1a;存储可执行文件&#xff0c;主要包含客户端和服务端启动程序&#xff0c;如mysql.exe、mysqld.exe等 /docs&#xff1a;存放一些文档 /include&#xff1a;用于放置一些头文件&#xff0c;如&#xff1a;mysql.h、mysqld_error.h 等 …

Promise.all和promise.race的应用场景举例

Promise.all( ).then( )适用于处理多个异步任务&#xff0c;且所有的异步任务都得到结果时的情况。 <template><div class"box"><el-button type"primary" plain click"clickFn">点开弹出框</el-button></div> &…

基于Jenkins自动化部署PHP环境---基于rsync部署

基于基于Jenkins自动打包并部署Tomcat环境_学习新鲜事物的博客-CSDN博客环境 准备git仓库 [rootgit ~]# su - git 上一次登录&#xff1a;五 8月 25 15:09:12 CST 2023从 192.168.50.53pts/2 上 [gitgit ~]$ mkdir php.git [gitgit ~]$ cd php.git/ [gitgit php.git]$ git --b…

读取SD卡图片bin文件显示LCD上

读取SD卡bin文件显示图片 Coding 环境搭建&#xff1a; 硬件平台&#xff1a;STM32H750XBH6开发环境&#xff1a;STM32CubeMX V6.8.1KEIL V5.28.0.0STM32H750固件版本&#xff1a;package V1.11.0仿真下载驱动&#xff1a;ST-Link 前言&#xff1a;STM32H750XBH6 的flash只…

改进YOLO系列:10.添加NAMAttention注意力机制

添加NAMAttention注意力机制 1. NAMAttention注意力机制论文2. NAMAttention注意力机制原理3. NAMAttention注意力机制的配置3.1common.py配置3.2yolo.py配置3.3yaml文件配置1. NAMAttention注意力机制论文 论文题目:NAM: Normalization-based Attention Module 论文…

BGP路由协议的那些事?(下)

BGP路由协议的那些事?(下) 上期问题:在BGP联盟内部的EBGP和IBGP对等体互相传递路由时,LP属性和MED属性是如何变化的呢? 还记得我们说BGP联盟的规则时,有两条关于LP属性和MED属性的规则怎么说来着: 1:路由的LOCAL_PREF属性在整个联盟中都被保留,而不仅仅是在为它们…

【水平垂直居中布局】CSS实现水平垂直居中的5种方法(附源码)

文章目录 写在前面涉及知识点1、子绝对定位父相对定位&#xff0c;子节点设置位移实现1.1效果1.2实现源码 2、子绝对定位父相对定位&#xff0c;子节点设置上下边距2.1 效果2.2 实现源码 3、利用flex布局实现3.1 效果3.2 实现源码 4、利用行高和文本水平居中设置4.1 效果4.2 实…

EasyPOI 实战总结

EasyPOI实战总结 简介 easypoi功能如同名字easy,主打的功能就是容易,让一个没见接触过poi的人员 就可以方便的写出Excel导出,Excel模板导出,Excel导入,Word模板导出,通过简单的注解和模板 语言(熟悉的表达式语法),完成以前复杂的写法 使用EasyPOI 环境搭建 # 1.引入相关依…

【PHP】PHP开发教程-PHP开发环境安装

1、PHP简单介绍 PHP&#xff08;全称&#xff1a;Hypertext Preprocessor&#xff09;是一种广泛使用的开放源代码脚本语言&#xff0c;特别适用于Web开发。它嵌入在HTML中&#xff0c;通过在HTML文档中添加PHP标记和脚本&#xff0c;可以生成动态的、个性化的Web页面。 PHP最…

【力扣】202. 快乐数 <哈希>

【力扣】202. 快乐数 编写一个算法来判断一个数 n 是不是快乐数。 【快乐数】 定义为&#xff1a; 对于一个正整数&#xff0c;每一次将该数替换为它每个位置上的数字的平方和。 然后重复这个过程直到这个数变为 1&#xff0c;也可能是 无限循环 但始终变不到 1。 如果这个过程…

VS中插入Qt插件后配置项目笔记

Project下要创建四个文件夹: bin(输出目录\工作目录) 、include(头文件目录) 、lib(动态库目录) 、src(源码目录) 一、主项目模块配置&#xff1a; 1.配置属性——>常规——>输出目录加入(..\..\bin\) 2.配置属性——>调试——>工作目录加入($(OutDir)) 备注&am…

openresty安装与网站发布

文章目录 安装依赖下载安装包解压安装包安装启动nginx配置环境变量配置开机启动发布静态网站 OpenResty 是一个基于 Nginx 与 Lua 的高性能 Web 平台&#xff0c;其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动…

ASCII编码表:字符对照表和值查询

ASCII码值32到126之间是可打印的字符&#xff0c;而ASCII码值0到31是控制字符&#xff0c;127是删除字符&#xff0c;它们在表格中没有对应的可见字符 ASCII码值字符0NUL (空字符)1SOH (标题开始)2STX (正文开始)3ETX (正文结束)4EOT (传输结束)5ENQ (传输结束)6ACK (确…

【业务功能篇84】微服务SpringCloud-ElasticSearch-Kibanan-电商实例应用

一、商品上架功能 ElasticSearch实现商城系统中全文检索的流程。 1.商品ES模型 商品的映射关系 PUT product {"mappings": {"properties": {"skuId": {"type": "long"},"spuId": {"type": "ke…

《Dive into Deep Learning》

《Dive into Deep Learning》&#xff1a;https://d2l.ai/ Interactive deep learning book with code, math, and discussionsImplemented with PyTorch, NumPy/MXNet, JAX, and TensorFlowAdopted at 500 universities from 70 countries 《动手学深度学习》中文版&#xff1…

微信小程序教学系列(6)

第六章&#xff1a;小程序商业化 第一节&#xff1a;小程序的商业模式 在这一节中&#xff0c;我们将探讨微信小程序的商业模式&#xff0c;让你了解如何将你的小程序变成一个赚钱的机器&#xff01; 1. 广告收入 小程序的商业模式之一是通过广告收入赚钱。你可以在小程序中…