这是我的 Rust 代码
#[no_mangle]
pub extern "C" fn get_name(){
println!("subham shaw");
}
这是我的java代码
// ExampleJNI.java
public class RustTest {
static {
// Load the Rust library
System.load("E:/Rust_pro/android_test/target/debug/sample.dll");
}
// Native method declarations
public native void get_name();
public static void main(String[] args) {
RustTest example = new RustTest();
example.get_name();
}
}
这是我的cargo.toml
[package]
name = "android_test"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
jni = "0.21.1"
[lib]
name = "sample"
crate-type = ["cdylib"]
我尝试了这段代码,但它不起作用,java抛出错误:
Exception in thread "main" java.lang.UnsatisfiedLinkError: 'void RustTest.get_name()'
at RustTest.get_name(Native Method)
at RustTest.main(RustTest.java:16)
如何解决这个问题
我尝试导出 rust 函数,以便可以使用 java 加载它
执行 JNI 时,在 Java 文件上运行以下命令很有用:
javac -h . RustTest.java
这将创建一个
RustTest.h
文件,其中包含您的本机类的 C 接口,您必须在 Rust 中实现该文件:让编译器为您思考。
现在,在此文件中您将看到必须遵守的相关声明,但在 Rust 而不是 C:
JNIEXPORT void JNICALL Java_RustTest_get_1name
(JNIEnv *, jobject);
首先要注意的是名称:该函数不仅仅是
get_name
,而是 Java_
+ package_name + class_name + function_name 的串联。
在您的特定情况下,package_name不适用,而function_name。我不确定
1
会发生什么,我认为 get_
是属性或其他东西的保留前缀...
现在是 Rust 代码,您还忘记了函数参数:
_env
:代表JVM。_obj
:是 this
对象。并且不要忘记 Java 函数应该声明为
"system"
,而不是 "C"
!
use jni::JNIEnv;
use jni::objects::JObject;
#[no_mangle]
pub extern "system" fn Java_RustTest_get_1name(_env: JNIEnv, _obj: JObject){
println!("subham shaw");
}
现在应该可以工作了。