gpt4 book ai didi

java - 如何在 JNI 中访问 jobject 的值

转载 作者:行者123 更新时间:2023-11-30 03:30:42 25 4
gpt4 key购买 nike

JNIEXPORT jbyteArray JNICALL Java_ramRead_MainClass_readRam
(JNIEnv *env, jobject, jobject len, jobject addr, jint pid)
{
jclass c = (*env).GetObjectClass(len);
jfieldID fid = (*env).GetFieldID(c, "len", "Ljava/math/BigInteger;");
std::cout << "Object Field: " << (*env).GetObjectField(len, fid);

struct iovec local[1];
struct iovec remote[1];
unsigned long long len1 = (*env).GetObjectField(len, fid) //This did not work out. the conversion to unsigned long long
jbyte buf[len];
jbyteArray buf1 = (*env).NewByteArray(len);

local[0].iov_base = buf;
local[0].iov_len = len;

remote[0].iov_base = (void *) addr;
remote[0].iov_len = len;

nread = process_vm_readv(pid, local, 1, remote, 1, 0);

(*env).SetByteArrayRegion(buf1, 0, len, buf);
return buf1;
}

这是我的 native 方法,如您所见,它接收 3 个参数作为参数,两个 jobject 和一个 int。这两个工作对象是大整数,最初它作为两个 int 和一个 long 参数恢复,但由于我现在需要传递大整数,所以我遇到了问题,或者我应该说几个。

目标:

我需要从 jobject len 中获取 BigInteger 值,然后我需要用它来初始化 jbyte buf[len] 的大小> , jbyteArray buf1 = (*env).NewByteArray(len)local[0].iov_len = len; 我当然不能只用 len 初始化它们 我需要从 len 中获取大整数值,然后用它初始化大小。然后我需要做同样的事情,使用 jobject addr 从中提取大整数值。

如有任何帮助,我们将不胜感激。

最佳答案

你的方法的问题是你试图访问 BigInteger 调用 len 的字段:

GetFieldID(c, "len", "Ljava/math/BigInteger;");

但是 BigInteger 没有这样的字段。

无法直接访问 BigInteger 的“值”。您可以从 JNI 做的最好的事情是将 BigInteger 转换为 jlong​​(通过调用 Java 方法 longValue,在 BigInteger) 并使用它。

但是,如果要以任何方式将 BigInteger 转换为 jlong​​,则使用 BigInteger 毫无意义。您将失去使用 BigInteger 获得的任何精度。因此不妨在 Java 中使用 long(它仍然适合您提到的值 0xffffffffff601000)。

此外,一个byte[]只能被一个int索引,所以即使你让buf大于它,它也赢了' 可从 Java 访问。

我建议使用直接 ByteBuffer 而不是 byte[],因为您不必跨缓冲区复制数据。

你会得到这样的东西:

private static native void readRam(ByteBuffer buff, long address, int pid);

然后在 C++ 中:

JNIEXPORT void JNICALL Java_Main_readRam
(JNIEnv *env, jclass, jobject byteBuffer, jlong addr jint pid) {

struct iovec local[1];
struct iovec remote[1];

void* buf = env->GetDirectBufferAddress(byteBuffer);
jlong len = env->GetDirectBufferCapacity(byteBuffer);

local[0].iov_base = buf;
local[0].iov_len = len;

remote[0].iov_base = (void *) addr;
remote[0].iov_len = len;

process_vm_readv(pid, local, 1, remote, 1, 0);
}

然后调用:

int bufferLength = ...;
long address = 0xffffffffff601000L;
int pid = ...;

ByteBuffer bb = ByteBuffer.allocateDirect(bufferLength);

readRam(bb, address, pid);

// use bb...

关于您的评论,您可以这样做:

StringBuilder sb = new StringBuilder();
while(bb.hasRemaining()) {
byte b = bb.get();
if((b >= 32 && b < 127) || b == 10) {
sb.append((char) b);
}
}
String result = sb.toString();

关于java - 如何在 JNI 中访问 jobject 的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44804660/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com