如何使用 JNI 从已运行的 JVM 获取 JavaVM 或 JNIEnv?

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

我正在做一个涉及 Rust 和 Java 的项目。我需要能够从 Rust 端使用 JNI,而无需 Java 端调用它(因为它不是我的代码)。到目前为止,我已经能够确保我的 DLL 被注入(在按键时打开一个小窗口,我一直在使用它进行调试)。

相关代码的简短示例如下:

use jni::sys::{JNI_GetCreatedJavaVMs, JNIInvokeInterface_};


let jvm_ptr = null_mut() as *mut *mut *const JNIInvokeInterface_;
let count = null_mut();

// hasn't crashed

JNI_GetCreatedJavaVMs(jvm_ptr, 1, count);  // https://docs.rs/jni/latest/jni/sys/fn.JNI_GetCreatedJavaVMs.html

// crashes

我的问题是:在这种情况下是否可以/如何获得 JNI 环境?

rust java-native-interface ffi dll-injection jnienv
3个回答
1
投票

您不能将空指针分块到

vmBuf
参数中,然后通过
vmBuf
告诉它
bufLen
指向长度为 1 的数组。翻译上面链接的 C++ 代码,我会做类似的事情

let mut count: jint = 0;
let check = JNI_GetCreatedJavaVMs(null_mut(), 0, &mut count);
assert!(check == JNI_OK);
let mut vms = vec![null_mut(); count as usize];
let check = JNI_GetCreatedJavaVMs(vms.as_mut_ptr(), vms.len() as i32, &mut count);
assert!(check == JNI_OK);
assert!(vms.len() == count as usize);

尽管这可能有点矫枉过正,因为只能有一个虚拟机。不过,检查计数可能是个好主意。


1
投票

在评论的帮助下,我让崩溃不再发生。诀窍是预先分配一个数组。

let jvm_ptr = Vec::with_capacity(1);
let count = null_mut();

JNI_GetCreatedJavaVMs(jvm_ptr.as_mut_ptr(), 1, count);

0
投票

我已经使用这个很多年了。可以抛光....

try {
     // how many JVMs is there?
     JNI_GetCreatedJavaVMs(NULL, 0, &number_of_JVMs);
 }
 catch (exception e)
 {
     int x = 0;
 }

 if (number_of_JVMs > 0)
 {
     JavaVM** buffer = new JavaVM * [number_of_JVMs];
     JNI_GetCreatedJavaVMs(buffer, number_of_JVMs, &number_of_JVMs); 
// 2. get the data
     jvm_handle = buffer[0];
     if (!jvm_handle == 0)
         return true;
     else return false;
 }
© www.soinside.com 2019 - 2024. All rights reserved.