rust工程
文章目录
- Cargo
- macOS配置rust环境
- vscode配置
- 目录结构
- Cargo.toml
- cargo命令
- hello world
- 跟web交互
- WebAssembly
- 跟Android交互
- 配置Android环境
- JNI例子
- NDK例子
Rust 是一种现代的、系统级的编程语言,它强调并发安全、内存安全和高性能。Rust 的设计目标是提供一种有着良好抽象能力,同时又能够保证代码运行效率和安全性的语言。它将内存安全、并发安全和数据竞争检测等特性作为语言的一部分,通过所有权系统、借用检查器和生命周期等机制来防止常见的编程错误。
下面是一些与 Rust 相关的工具和库的介绍:
-
Cargo:
Cargo 是 Rust 的包管理工具和构建系统。它能够自动管理 Rust 项目的依赖关系,并提供命令行工具来构建、测试和运行项目。Cargo 简化了 Rust 项目的创建和管理过程,使得开发者可以更专注于编写代码而不用过多关注构建细节。 -
Clippy:
Clippy 是 Rust 的静态代码分析工具,它能够检测出一些潜在的代码问题和不良习惯,并给出相应的建议。Clippy 可以帮助开发者编写更规范、更高质量的 Rust 代码。 -
Rust 文档(Rust Docs):
Rust Docs 是 Rust 官方提供的文档工具,用于生成和浏览 Rust 标准库和第三方库的文档。它为 Rust 开发者提供了一个方便的方式来查阅和学习 Rust 相关的文档。 -
Rust 标准库(Rust Standard Library):
Rust 标准库是 Rust 语言的核心库,它提供了许多常用的数据结构、算法和系统调用等功能。开发者可以直接使用标准库中的类型和函数,以快速构建高效、安全的 Rust 程序。 -
Rust 编译器(rustc):
Rust 编译器是将 Rust 代码编译为可执行文件或库的工具。它负责解析、类型检查、代码生成等编译过程,并生成适应目标平台的机器码。Rust 编译器是 Rust 语言的核心组件之一,它实现了 Rust 语言规范,并负责将 Rust 代码转化为可执行的程序。
这些工具和库都是 Rust 生态系统中重要的组成部分,它们与 Rust 的设计理念和目标相辅相成,使得开发者能够更加高效地编写、测试和维护 Rust 项目。无论是初学者还是有经验的开发者,对于这些工具的了解和使用都能够提升开发效率和代码质量。
Cargo
Cargo 是 Rust 的官方构建工具和包管理器。它用于帮助开发者构建、测试和管理 Rust 项目,简化了项目的依赖管理、构建配置和发布流程。下面详细介绍一下 Cargo 的主要功能和用法:
-
创建项目: 使用 Cargo 可以快速创建一个新的 Rust 项目。通过运行
cargo new <project_name>
命令,在当前目录下生成一个新的项目文件夹,并自动生成了一个简单的目录结构和必要的文件,包括Cargo.toml
、src/main.rs
等。 -
依赖管理: Cargo 管理 Rust 项目的依赖关系。在项目的
Cargo.toml
文件中,可以指定项目所需要的外部依赖库及其版本。当构建项目时,Cargo 会自动下载并编译这些依赖库,并将其集成到项目中。可以使用cargo build
命令来构建项目并处理依赖关系。 -
构建项目: Cargo 提供了简洁的命令行接口,可以用于构建 Rust 项目。运行
cargo build
命令将会编译项目的源代码,并生成可执行文件或库文件。Cargo 会根据项目的依赖关系自动解析和编译相关的代码。 -
运行项目: 使用
cargo run
命令可以方便地运行 Rust 项目。Cargo 会自动编译项目并执行生成的可执行文件。如果项目是一个库,可以使用cargo test
命令来运行项目中的测试用例。 -
测试项目: Cargo 提供了内置的测试框架和命令,用于编写和运行测试用例。在项目中的
src
目录下创建一个名为tests
的子目录,并在其中编写测试用例。然后使用cargo test
命令运行测试,并查看测试结果。 -
发布项目: 使用 Cargo 可以方便地发布 Rust 项目。通过运行
cargo build --release
命令,Cargo 会进行优化编译,生成一个发布版本的可执行文件。然后可以将生成的可执行文件部署到生产环境中。 -
文档生成: Cargo 提供了文档生成工具,可以生成项目的文档。在项目中的注释中添加文档注解,并使用
cargo doc
命令生成文档。生成的文档会包含项目的结构、函数、模块等信息,并可以通过浏览器进行查看。 -
更新依赖: 当项目依赖的库有新的版本发布时,可以使用 Cargo 更新依赖关系。运行
cargo update
命令,Cargo 会检查项目的依赖关系,并下载最新的版本。
除了上述功能,Cargo 还提供了其他一些辅助功能,例如初始化 Git 仓库、自动下载编译工具链(Rustup)、发布到 Cargo 社区等。这些功能使得 Cargo 成为 Rust 开发中必不可少的工具,极大地简化了项目的管理和构建过程,提高了开发效率。
macOS配置rust环境
在 macOS 上配置 Rust 环境,可以按照以下步骤进行:
-
安装 Homebrew(如果未安装):
打开终端,并执行以下命令来安装 Homebrew:/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
-
安装 Rust 编程语言:
在终端中执行以下命令来安装 Rust:curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
这将下载并运行 Rust 安装脚本。
-
配置环境变量:
安装完成后,脚本会提示你将 Rust 相关的可执行文件路径添加到环境变量中。请按照提示选择「2」或输入「2」,然后按 Enter 键。 -
初始化 Rust 环境:
执行以下命令初始化 Rust 环境:source $HOME/.cargo/env
-
验证安装:
在终端中执行以下命令验证 Rust 是否成功安装:rustc --version cargo --version
-
安装 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 开发环境时,以下是几个常用的插件推荐:
-
rust-analyzer:这是官方提供的 Rust 插件,是一个功能强大的 Rust 语言服务器,它提供了智能代码补全、重构建议、错误检查等高级功能。
-
Crates by serayuzgur:这个插件提供了对 Cargo.toml 和 Cargo.lock 文件的支持,可以方便地查看和管理项目的依赖关系。
-
CodeLLDB by Vadim Chugunov:如果你需要在 VS Code 中进行 Rust 代码的调试,这个插件可以与 LLDB 调试器集成,提供了强大的调试功能。
-
Better TOML by bungcip:这个插件提供了对 TOML 文件的语法高亮和格式化支持,对于编辑 Cargo.toml 文件来说非常实用。
-
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 的常用命令列表:
-
cargo new
:创建一个新的 Rust 项目。 -
cargo build
:构建项目,编译源代码并处理依赖关系。 -
cargo run
:运行项目,编译并执行生成的可执行文件。 -
cargo test
:运行测试用例。 -
cargo bench
:运行基准测试。 -
cargo doc
:生成项目文档。 -
cargo clean
:清理项目构建产生的临时文件和目录。 -
cargo update
:更新项目的依赖库。 -
cargo init
:初始化当前目录为一个 Rust 项目。 -
cargo check
:检查代码是否可以成功编译,但不生成可执行文件。 -
cargo fix
:自动修复一些编译警告和错误。 -
cargo publish
:发布项目到 crates.io,Rust 社区的包管理平台。 -
cargo install
:安装一个二进制包程序到系统路径。 -
cargo uninstall
:卸载一个已安装的二进制包程序。 -
cargo package
:生成一个用于发布的压缩包。 -
cargo metadata
:显示项目的元数据信息,依赖关系等。 -
cargo fmt
:格式化源代码。 -
cargo clippy
:运行 Clippy(Rust 的 lint 工具)对代码进行静态分析。 -
cargo doc --open
:生成文档并在浏览器中打开。 -
cargo build --release
:生成发布版本的可执行文件。 -
cargo build --target <target>
:指定目标平台进行构建。 -
cargo build --features <features>
:启用指定的特性进行构建。 -
cargo build --no-default-features
:禁用默认特性进行构建。 -
cargo build --all
:构建项目及其所有依赖。 -
cargo build --workspace
:在工作区中构建所有子项目。 -
cargo build --lib
:只构建项目中的库文件。 -
cargo build --bin <name>
:只构建指定名称的可执行文件。 -
cargo build --example <name>
:只构建指定名称的示例程序。 -
cargo build --tests
:只构建项目中的测试目标。 -
cargo build --benches
:只构建项目中的基准测试目标。 -
cargo build --target-dir <dir>
:指定构建输出的目录。 -
cargo build --all-features
:启用所有特性进行构建。 -
cargo build --no-default-runtime
:禁用默认运行时(仅适用于编写运行时的 Crate)。 -
cargo test -- --test-threads=<num>
:设置并发运行测试的线程数。 -
cargo test -- <pattern>
:只运行与指定模式匹配的测试。 -
cargo test -- --ignored
:运行被标记为#[ignore]
的测试。 -
cargo test --release
:以发布模式运行所有测试。 -
cargo doc --no-deps
:生成项目文档,但不包含依赖库的文档。 -
cargo run -- <args>
:在编译并运行项目时传递参数。 -
cargo check --all-targets
:检查项目及其所有目标的代码是否可以成功编译。 -
cargo fix --edition
:自动升级代码到指定的 Rust 版本。 -
cargo fix --allow-dirty
:允许在 Git 工作目录中运行cargo fix
。 -
cargo publish --dry-run
:发布前进行 dry-run,检查是否有错误。 -
cargo publish --allow-dirty
:允许在 Git 工作目录中运行cargo publish
。 -
cargo install <crate>
:安装指定的 Crate。 -
cargo install-update <crate>
:更新指定的 Crate。 -
cargo uninstall <crate>
:卸载指定的 Crate。 -
cargo search <query>
:在 crates.io 中搜索包。 -
cargo clean --package <spec>
:清理指定的 Package。 -
cargo metadata --format-version <version>
:指定元数据格式的版本。
这些是常用的 Cargo 命令,可以帮助你管理 Rust 项目的构建、测试、文档生成、依赖管理和发布等任务。你可以通过在命令行中输入 cargo --help
来查看更多命令以及它们的详细使用说明。
hello world
要开始你的第一个 Rust “Hello, World!” 项目,按照以下步骤进行:
-
安装 Rust 编程语言:首先,确保您已在计算机上安装了 Rust。可以访问 Rust 官方网站,按照指示下载并安装 Rust。
-
创建新项目:打开终端或命令提示符,导航到要创建项目的目录,并运行以下命令来创建一个新的 Rust 项目:
cargo new hello_world
这将在当前目录下创建一个名为 “hello_world” 的新目录,并自动生成一些初始代码。
-
进入项目目录:运行以下命令以进入新创建的项目目录:
cd hello_world
-
编辑代码:使用你喜欢的文本编辑器打开
src/main.rs
文件,并将以下代码复制粘贴到文件中:fn main() {println!("Hello, World!"); }
-
构建和运行项目:返回终端或命令提示符,运行以下命令来构建和运行你的项目:
cargo run
Rust 的构建系统 Cargo 将编译项目并运行生成的可执行文件。你应该会在终端上看到输出 “Hello, World!”。
恭喜!你已经成功创建并运行了你的第一个 Rust “Hello, World!” 项目。从这个简单的示例开始,你可以继续学习和探索 Rust 编程语言的更多方面。
跟web交互
Rust 可以与 Web 进行交互,使你能够构建 Web 应用程序、API 和后端服务。下面是一些可以帮助你在 Rust 中进行 Web 交互的常见方法:
-
Web 框架:使用 Rust 的 Web 框架可以简化 Web 开发过程,并提供路由、请求处理、中间件等功能。一些流行的 Rust Web 框架包括 Rocket、Actix-web 和 Warp。
-
HTTP 客户端和服务器:Rust 提供了多个库用于构建 HTTP 客户端和服务器。例如,reqwest 是一个常用的 HTTP 客户端库,hyper 是一个强大的 HTTP 服务器库。
-
数据库访问:与 Web 相关的应用程序通常需要与数据库进行交互。Rust 提供了各种数据库连接库和 ORM(对象关系映射)工具,例如 Diesel、sqlx 和 rusqlite。
-
模板引擎:用于生成动态 HTML 页面的模板引擎在 Web 开发中非常有用。Rust 中一些流行的模板引擎包括 Tera 和 Handlebars。
-
WebAssembly(Wasm):Rust 具备编写 WebAssembly 模块的能力,这使得你可以在 Web 浏览器中运行原生速度的 Rust 代码。你可以使用 wasm-bindgen 和 wasm-pack 工具来构建和集成 Rust 和 JavaScript 之间的接口。
-
WebSocket:Rust 提供了用于 WebSocket 通信的库,如 tokio-tungstenite 和 actix-web 的 WebSocket 功能。
以上只是一些在 Rust 中进行 Web 交互的方法示例,你可以根据具体需求选择合适的库和工具。Rust 社区拥有丰富的资源和文档,可以帮助你深入了解和学习 Rust 的 Web 开发。
WebAssembly
以下是一个使用 Rust 和 WebAssembly(Wasm)进行交互的示例:
首先,确保你已经安装了 Rust 和 wasm-pack 工具。
-
创建新的 Rust 项目:
打开终端或命令提示符,导航到要创建项目的目录,并运行以下命令来创建一个新的 Rust 项目:cargo new wasm_example cd wasm_example
-
添加依赖:
在项目的根目录中,打开Cargo.toml
文件,并添加以下代码来添加 wasm-bindgen 和 js-sys 的依赖:[lib] crate-type = ["cdylib"][dependencies] wasm-bindgen = "0.2" js-sys = "0.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
函数,它接受一个字符串参数,并在控制台输出问候消息。 -
生成 Wasm 模块:
在终端中运行以下命令来生成 Wasm 模块:wasm-pack build --target web
这将使用 wasm-pack 工具将 Rust 代码编译为 WebAssembly 模块,并生成与 JavaScript 交互的必要代码。
-
创建 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
函数。 -
启动本地服务器:
在终端中运行以下命令来启动一个简单的本地服务器:python -m http.server
-
运行示例:
打开浏览器并访问http://localhost:8000
,然后打开浏览器的控制台。你应该会看到控制台输出了 “Hello, Alice!”。
通过上述步骤,你可以在 Rust 中创建一个简单的 WebAssembly 模块,并与 JavaScript 进行交互。你可以根据需要扩展这个示例,并使用更多的 Rust 函数与 JavaScript 进行交互。
跟Android交互
当你想要在 Android 平台上使用 Rust 与 Java 进行交互时,下面是一些具体的步骤和工具可以帮助你实现这一目标:
-
使用 JNI(Java Native Interface):JNI 提供了一种方式,使得 Java 和本地代码能够进行交互。你可以使用 Rust 编写本地代码,并通过 JNI 接口与 Android 的 Java 代码进行通信。为了在 Rust 中与 JNI 交互,你可以使用
jni
或rust-jni
等库来编写相应的绑定代码。需要完成的步骤:
- 编写 Rust 的绑定代码,将 Rust 函数暴露给 JNI。
- 生成动态链接库(
.so
文件)。 - 在 Android 项目中使用 JNI 接口调用 Rust 函数。
-
使用 NDK(Native Development Kit):NDK 允许你使用 C、C++ 或其他本地语言来开发 Android 应用程序。你可以使用 Rust 作为 C 或 C++ 的替代语言,并在 NDK 中构建包含 Rust 代码的本地库。然后,你可以使用 Java 代码通过 JNI 调用这些本地库。
需要完成的步骤:
- 创建 Android NDK 项目,并配置好 Rust 的构建环境。
- 编写 Rust 代码并构建共享库(
.so
文件)。 - 使用 JNI 接口在 Java 代码中调用本地库中的函数。
-
使用 FFI(Foreign Function Interface):FFI 允许不同语言之间进行函数调用和数据传递。你可以使用 Rust 的 FFI 功能,将 Rust 函数暴露给其他语言,比如 Java。通过这种方式,你可以在 Android 的 Java 代码中直接调用 Rust 函数。
需要完成的步骤:
- 使用 Rust 的
#[no_mangle]
和extern
关键字将函数标记为可供外部调用。 - 根据 FFI 规范编写 Java 代码来调用 Rust 函数。
- 在 Android 项目中将 Rust 代码和 Java 代码一起编译和构建。
- 使用 Rust 的
-
使用
rust-android-gradle
插件:rust-android-gradle
是一个方便的工具,可用于将 Rust 代码集成到 Android 项目中。它可以自动处理 Rust 代码的构建和链接,并与 Gradle 构建系统集成。需要完成的步骤:
- 在 Android 项目的 Gradle 文件中添加
rust-android-gradle
插件的依赖。 - 创建 Rust 模块并设置构建配置。
- 在 Android 项目中使用预生成的 Rust 库。
- 在 Android 项目的 Gradle 文件中添加
请注意,在实施任何方法之前,你需要确保已经按照相应工具和库的文档进行了正确的配置和设置。每种方法都有其优势和适用场景,因此根据需求选择最适合你的方法。
希望这些详细的步骤能够帮助你更好地理解 Rust 与 Android 的交互,并实现你的项目需求。
配置Android环境
要正确安装和配置 Android NDK,请按照以下步骤进行操作:
-
下载 Android NDK:访问 Android NDK 的官方网站下载适合你操作系统的最新版本。
-
解压缩文件:将下载的 NDK 压缩文件解压到你选择的位置。例如,你可以将其解压到
~/android-ndk
目录下。 -
配置环境变量:打开终端并编辑你的 shell 配置文件(例如
~/.bashrc
或~/.zshrc
)。在文件末尾添加以下行(假设你将 NDK 解压缩到了~/android-ndk
目录):export ANDROID_NDK_HOME=~/android-ndk export PATH=$PATH:$ANDROID_NDK_HOME
保存文件后执行以下命令使配置立即生效:
source ~/.bashrc
或者你也可以重新启动终端。
-
测试安装:在终端中运行以下命令验证是否正确安装和配置了 Android NDK:
ndk-build --version
如果成功安装并配置,将显示 NDK 版本信息。
-
安装交叉编译目标:运行以下命令来安装 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
-
配置链接器和编译参数:创建一个名为
$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"
-
测试编译:现在,你可以尝试使用 Cargo 构建你的项目,并将目标设置为 Android 平台,例如:
cargo build --target aarch64-linux-android
通过按照以上步骤配置 Rust 的交叉编译环境,你应该能够开始在 Android 平台上使用 Rust 进行交叉编译了。
JNI例子
当使用 JNI 实现 Rust 与 Android 的交互时,可以使用以下示例来说明具体步骤。假设你希望在 Android 应用程序中调用一个计算两个整数和的 Rust 函数。
-
创建一个名为
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() }
-
在
Cargo.toml
文件中添加以下内容:[lib] crate-type = ["cdylib"]
-
使用以下命令在 Rust 中构建共享库文件:
cargo build --target aarch64-linux-android
上述命令将在
target/aarch64-linux-android/debug/librust_lib.so
中生成共享库文件。 -
在 Android 项目中的
app
模块下的src/main
目录中创建一个名为jni
的文件夹,并在其中创建一个native-lib.cpp
文件。 -
在
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对应的目录中。 -
配置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)
-
在 Android 项目的 Java 类中,添加以下方法:
public class MainActivity extends AppCompatActivity {static {System.loadLibrary("native-lib");}public native String stringFromJNI(String name);// ... }
-
在
MainActivity.java
中的任何适当的方法中调用stringFromJNI()
方法,并向其传递一个字符串参数:String greeting = stringFromJNI("Stone " + new Date().toString()); Log.d("MainActivity", greeting);
这样,在 Android 应用程序中运行时,将调用 Rust 函数并输出日志中的问候语。
NDK例子
当使用 Rust 和 Android NDK 进行开发时,以下是一个详细的示例,展示如何在 Android 项目中使用 Rust 编写并调用函数。
-
创建 Rust 项目:
在终端中执行以下命令,创建一个名为
rust-ndk
的 Rust 项目:cargo new rust-ndk
进入项目目录:
cd rust-ndk
-
添加依赖项:
打开项目中的
Cargo.toml
文件,并添加ndk
、jni
和libc
作为依赖项:[lib] crate-type = ["cdylib"] path = "src/jni.rs"[dependencies] jni = "0.21.1"
-
创建 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
字符串。 -
构建 Rust 项目:
在终端中执行以下命令构建 Rust 项目:
cargo build --target aarch64-linux-android --release
-
创建 Android 项目:
使用 Android Studio 创建一个新的 Android 项目,并导航到
app/src/main
目录。 -
添加 Rust 动态链接库:
将生成的
.so
文件复制到app/src/main/jniLibs
目录下(如果没有该目录则自行创建)。例如,将../rust-ndk/target/release/librust_ndk.so
文件复制到app/src/main/jniLibs/arm64-v8a/
目录下。 -
创建 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 函数并输出日志中的问候语。
相关文章:
rust工程
文章目录 CargomacOS配置rust环境vscode配置 目录结构Cargo.tomlcargo命令hello world 跟web交互WebAssembly 跟Android交互配置Android环境JNI例子NDK例子 Rust 是一种现代的、系统级的编程语言,它强调并发安全、内存安全和高性能。Rust 的设计目标是提供一种有着良…...

Java并发工具类
JDK并发包中常用并发工具类: CountDownLatch、CyclicBarrier和Semaphore工具类提供了一种并发流程控制的手段; Exchanger工具类则提供了在线程间交换数据的一种手段。 等待多线程完成的CountDownLatch CountDownLatch允许一个或多个线程等待其他线程完成…...

晨控CK-GW208与三菱L系列PLC以TCP通讯手册
晨控CK-GW208是一款支持标准工业以太网协议的IO-LINK主站网关,方便用户快速便捷的集成到 PLC 等控制系统中。 CK-GW208主站网关集成 8 路 IO-LINK 通信端口,采用即插即用模式,无需繁琐的配置,减轻现场安装调试的工作量。为了满足…...

c++11 标准模板(STL)(std::basic_istringstream)(五)
定义于头文件 <sstream> template< class CharT, class Traits std::char_traits<CharT> > class basic_istringstream;(C11 前)template< class CharT, class Traits std::char_traits<CharT>, class Allocator std::allo…...
【案例教程】高分论文密码:大尺度空间模拟预测与数字制图
尺度空间模拟预测和数字制图技术和不确定性分析广泛应用于高分SCI论文之中,号称高分论文密码。大尺度模拟技术可以从不同时空尺度阐明农业生态环境领域的内在机理和时空变化规律,又可以为复杂的机理过程模型大尺度模拟提供技术基础。在本次培训中&#x…...
uniapp 自定义手机顶部状态栏(适配状态栏高度)
开启页面自定义导航栏功能 uniapp 在 pages.json 页面设置了全局的 globalStyle 的 "navigationStyle": "custom" 或单页面的 style 的 "navigationStyle": "custom" 之后页面顶部就没有自带的导航栏了,这时用户可自定义该…...

【LeetCode】1448.统计二叉树中好节点的数目
题目 给你一棵根为 root 的二叉树,请你返回二叉树中好节点的数目。 「好节点」X 定义为:从根到该节点 X 所经过的节点中,没有任何节点的值大于 X 的值。 示例 1: 输入:root [3,1,4,3,null,1,5] 输出:4 …...

C语言基础之——数组
前言:本篇文章,我们将对一维数组,和二维数组进行展开式的讲解,并进行实际应用。 目录 一.一维数组 1.一维数组的创建和初始化 (1)数组的创建 (2)数组的初始化 2.一维数组的使用…...
c# 插入排序
插入排序(Insertion Sort):将未排序的元素逐个插入到已排序的序列中的正确位置。 原始数据:{4,3,2,90,10} 第一个循环j0 首先取出索引为1的元素 3 ,索引为0的元素4&…...

action和mutation之间的利用 代码解释
场景:购物车点击按钮 context.commit(‘changeCount’, { goodsNum, goodsId })解释这段代码 这段代码是在使用 Vuex 进行状态管理时常见的一种写法。下面对代码进行解释: context.commit 是 Vuex 中的一个方法,用于触发一个名为 changeC…...

WPF基础入门-Class4-WPF绑定
WPF基础入门 Class4:WPF绑定 1、cs文件中设置需要绑定的数据: public partial class Class_4 : Window{public Class_4(){InitializeComponent();List<Color> test new List<Color>();test.Add(new Color() { Code "Yellow",…...

【广州华锐互动】VR高校虚拟实验教学平台提供丰富的资源支持,提高教学效果
随着科技的不断进步,虚拟现实(VR)技术已经逐渐渗透到各个领域,其中包括教育。 广州华锐互动利用VR虚拟现实技术打造的VR高校虚拟实验教学平台,是一种新型的教学工具,它提供了一个在线的教学资源管理平台,包含教学平台、…...

pytorch学习(7)——神经网络优化器torch.optim
1 optim 优化器 PyTorch神经网络优化器(optimizer)通过调整神经网络的参数(weight和bias)来最小化损失函数(Loss)。 学习链接: https://pytorch.org/docs/stable/optim.html 1.1 优化器基类 使…...
leetcode做题笔记101. 对称二叉树
给你一个二叉树的根节点 root , 检查它是否轴对称。 思路一:递归 bool isSymmetric(struct TreeNode* root){if (root NULL) return true;return fun(root->left, root->right); }int fun(struct TreeNode* l_root, struct TreeNode* r_root) {…...
边缘计算相关概念--学习笔记
一.边缘计算概念 边缘计算将数据的处理,应用程序的运行甚至一些功能服务的实现,由网络中心下放到网络边缘的节点上,在网络边缘侧的智能网关上就近采集并且处理数据,不需要将大量未处理的数据上传到远程的大数据平台。边缘计算理论…...
flutter windows编译错误 flutter_assemble.vcxproj
flutter 编译windows是出现错误。 [ 44 ms] d:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(248,5): error MSB8066: ��E:\work\kkview_kuaichuan\kkview_kuaichuan\build\windows\C…...
通过运行中的容器生成 Docker Compose 配置文件
背景 笔者之前有一次不小心删除了原始的 docker-compose.yml 文件,不过正在运行的 Docker 容器还在,找了许久,发现一个方法可以从这些容器中生成一个等效的 Docker Compose 配置文件。本文将介绍使用 autocompose 工具从正在运行的容器中反向…...
rancher界面无法登陆问题解决,登录超时;
1.找到rancher主机,查看日志 docker ps | grep rancher # rancher 容器 名称 jolly_ptolemy docker logs -f jolly_ptolemy 日志提示, java.sql.SQLException: Got error 28 from storage engine,磁盘满了 2.磁盘管理 df -h #查看磁盘使…...

Django(6)-django项目自动化测试
Django 应用的测试应该写在应用的 tests.py 文件里。测试系统会自动的在所有以 tests 开头的文件里寻找并执行测试代码。 我们的 polls 应用现在有一个小 bug 需要被修复:我们的要求是如果 Question 是在一天之内发布的, Question.was_published_recentl…...
【AUTOSAR】【CAN通信】CanNm
目录 一、概述 二、说明 三、功能说明 3.1 协调算法 3.2 操作模式 3.2.1 网络模式...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...

MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...

CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...

让AI看见世界:MCP协议与服务器的工作原理
让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
【Go语言基础【12】】指针:声明、取地址、解引用
文章目录 零、概述:指针 vs. 引用(类比其他语言)一、指针基础概念二、指针声明与初始化三、指针操作符1. &:取地址(拿到内存地址)2. *:解引用(拿到值) 四、空指针&am…...
Java编程之桥接模式
定义 桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...