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;
}
这是我的原生方法,正如您所看到的,它接收3个参数作为参数两个jobject
和一个int
。这两个工作是大整数,
最初它作为参数2复活int
和一个long
但是因为我需要传递大整数现在我有问题或者我应该说几个。
目标:
我需要从BigInteger
获取jobject len
值,然后我需要使用它来初始化jbyte buf[len]
,jbyteArray buf1 = (*env).NewByteArray(len)
和local[0].iov_len = len;
的大小当然不能只用len
初始化它们我需要从len
获取大整数值,然后用它初始化大小。
然后我需要做同样的事情,使用jobject addr从中提取大整数值。
任何帮助都将不胜感激。
答案 0 :(得分:0)
您的方法存在的问题是您尝试访问BigInteger
来电len
的字段:
GetFieldID(c, "len", "Ljava/math/BigInteger;");
但是BigInteger
没有这样的字段。
无法访问&#34;值&#34;直接BigInteger
您可以从JNI做的最好的事情是将BigInteger
转换为jlong
(通过调用longValue
上的Java方法BigInteger
并使用它。
但是,如果您以任何方式将其转换为BigInteger
,则使用jlong
毫无意义。您将失去使用BigInteger
所获得的任何精确度。所以不妨在Java中使用long
(它仍然适合你提到的值0xffffffffff601000
。)
此外,byte[]
只能使用int
编入索引,因此即使您使buf
大于ByteBuffer
,也无法通过Java访问。
我建议使用直接byte[]
代替private static native void readRam(ByteBuffer buff, long address, int pid);
,因为您不必跨缓冲区复制数据。
你得到这样的东西:
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);
}
然后在C ++中:
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();
关于你的评论,你可以这样做:
platformio platform install https://github.com/platformio/platform-espressif8266.git#feature/stage