Rust JNI开发工具jni-sys-macros的使用,实现Java本地接口的Rust宏代码自动生成
Rust JNI开发工具jni-sys-macros的使用,实现Java本地接口的Rust宏代码自动生成
安装
在项目目录中运行以下Cargo命令:
cargo add jni-sys-macros
或在Cargo.toml中添加以下行:
jni-sys-macros = "0.1.0"
使用示例
jni-sys-macros是一个用于简化Rust与Java Native Interface(JNI)交互的宏库,它可以自动生成JNI相关的Rust代码。
// 导入必要的依赖
use jni_sys_macros::jni_export;
// 使用jni_export宏自动生成JNI导出函数
#[jni_export("com.example.MyClass")]
pub extern "system" fn Java_com_example_MyClass_helloFromRust(
env: *mut jni_sys::JNIEnv,
_class: jni_sys::jclass,
) -> jni_sys::jstring {
// 获取JNIEnv方法
let env = unsafe { &*env };
// 创建Java字符串
let output = "Hello from Rust!".to_string();
let jstring = unsafe {
(env).NewStringUTF.unwrap()(output.as_ptr() as *const i8)
};
jstring
}
完整示例
这是一个完整的Rust JNI项目示例,展示了如何使用jni-sys-macros与Java进行交互:
// Cargo.toml依赖
[dependencies]
jni-sys = "0.3"
jni-sys-macros = "0.1"
// src/lib.rs
use jni_sys_macros::jni_export;
#[jni_export("com.example.MathOperations")]
pub extern "system" fn Java_com_example_MathOperations_addNumbers(
_env: *mut jni_sys::JNIEnv,
_class: jni_sys::jclass,
a: jni_sys::jint,
b: jni_sys::jint,
) -> jni_sys::jint {
a + b
}
#[jni_export("com.example.MathOperations")]
pub extern "system" fn Java_com_example_MathOperations_getGreeting(
env: *mut jni_sys::JNIEnv,
_class: jni_sys::jclass,
) -> jni_sys::jstring {
let env = unsafe { &*env };
let greeting = "Hello from Rust MathOperations!".to_string();
unsafe { (env).NewStringUTF.unwrap()(greeting.as_ptr() as *const i8) }
}
对应的Java代码示例:
package com.example;
public class MathOperations {
// 声明native方法
public native static int addNumbers(int a, int b);
public native static String getGreeting();
static {
// 加载Rust生成的动态库
System.loadLibrary("math_operations");
}
public static void main(String[] args) {
System.out.println(getGreeting());
System.out.println("2 + 3 = " + addNumbers(2, 3));
}
}
构建和运行
- 构建Rust库为动态库:
cargo build --release
-
将生成的动态库放在Java的库路径中
-
编译并运行Java程序
特性
- 自动生成符合JNI命名规范的函数名
- 简化JNI类型转换
- 提供类型安全检查
- 减少样板代码
许可证
jni-sys-macros采用MIT或Apache-2.0双许可证。
1 回复
Rust JNI开发工具jni-sys-macros使用指南
简介
jni-sys-macros
是一个用于简化 Rust 与 Java 通过 JNI (Java Native Interface) 交互的宏库。它可以帮助开发者自动生成 JNI 相关的样板代码,使 Rust 与 Java 的互操作更加方便和安全。
安装
在 Cargo.toml
中添加依赖:
[dependencies]
jni-sys-macros = "0.1"
jni = "0.21" # 通常也需要jni crate
主要功能
1. jni_fn!
宏
自动生成符合 JNI 规范的函数声明和转换代码。
use jni_sys_macros::jni_fn;
// 自动生成JNI规范的函数名和参数转换
#[jni_fn("com.example.MyClass")]
pub fn say_hello(env: *mut jni::sys::JNIEnv, obj: jni::sys::jobject, name: jni::sys::jstring) {
let env = unsafe { jni::JNIEnv::from_raw(env).unwrap() };
let name: String = env.get_string(name.into()).unwrap().into();
println!("Hello, {} from Rust!", name);
}
2. jni_impl!
宏
为 Rust 结构体自动生成 JNI 接口实现。
use jni_sys_macros::jni_impl;
struct MyRustStruct {
counter: i32,
}
#[jni_impl("com.example.MyJavaClass")]
impl MyRustStruct {
#[jni_fn]
pub fn new() -> Self {
MyRustStruct { counter: 0 }
}
#[jni_fn]
pub fn increment(&mut self) -> i32 {
self.counter += 1;
self.counter
}
}
3. 异常处理
自动将 Rust 错误转换为 Java 异常:
#[jni_fn("com.example.MyClass")]
pub fn risky_operation(env: *mut jni::sys::JNIEnv, obj: jni::sys::jobject) -> jni::sys::jint {
let result = || -> Result<i32, String> {
// 可能失败的操作
if some_condition {
Ok(42)
} else {
Err("Something went wrong".to_string())
}
}();
result.unwrap_or_else(|e| {
let env = unsafe { jni::JNIEnv::极简主义风格图片,包含一个白色背景和黑色线条绘制的房子轮廓,门和窗户也是简单的黑色线条。屋顶是三角形,房子主体是长方形,门在中间,两边各有一个小方窗。没有阴影或颜色,只有干净利落的黑线。