如何编译Rust代码使其功能可以通过Java调用

问题描述 投票:0回答:1

这是我的 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 加载它

java function rust hyperlink export
1个回答
0
投票

执行 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");
}

现在应该可以工作了。

© www.soinside.com 2019 - 2024. All rights reserved.