- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
Java 代码:
public class MainClass
{
static
{
System.load("/home/chronic/workspace/ramRead/src/libRamRead.so");
}
private native String readRam(int len, long addr, int pid);
private native int readSize();
public static void main(String[] args)
{
MainClass app = new MainClass();
String x = app.readRam(4096, 0x55c5520b5000L, 4435);
//System.out.println("HEY THERE");
// System.out.println("I BEGIN HERE");
System.out.println(x.length());
//int test = app.readSize();
//System.out.println(test);
}
}
这是我的原生函数 (C++)
JNIEXPORT jstring JNICALL Java_ramRead_MainClass_readRam
(JNIEnv *env, jobject, jint len, jlong addr, jint pid)
{
struct iovec local[1];
struct iovec remote[1];
char buf[len];
jstring result;
//jcharArray buf = (*env).NewCharArray(len);
//jcharArray buf1 = (*env).NewCharArray(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);
//printf("len %d, pid %d, addr %li, buf %c, size of buf %d ", len, pid, addr, buf, sizeof(buf));
printf("\nTHIS MUCH: %d\n", nread);
for(int i=0; i<4096; i++){
printf("%c", buf[i]);
}
//(*env).SetCharArrayRegion(buf1, 0, len, buf);
result = (*env).NewStringUTF(buf);
//printf("RESULT: %s", (*env).GetStringUTFLength(result));
return result;
}
我的目标:
让C++中的native函数读取ram中的内容,然后以字符串或char数组的形式返回给java做进一步处理。
问题:
jstring 结果
的返回值不是我预期的 java 中的值,存在几个问题,首先它的长度为 7 而不是预期的 4096。另一个问题是输出是荒谬的。我有另一个用 C++ 编写的程序,它基本上读取 RAM 的内容,然后将它们打印到控制台。这是下面的代码,它就像一个魅力。我知道从哪个地址读取,我知道期望的结果,只要我使用 C++,它就可以正常工作,但只要我使用相同的 JNI出现上述问题前的方法。
#include <jni.h>
#include "ramRead_MainClass.h"
#include <sys/uio.h>
static ssize_t nread;
JNIEXPORT jbyteArray JNICALL Java_ramRead_MainClass_readRam
(JNIEnv *env, jobject, jint len, jlong addr, jint pid)
//JNIEXPORT jbyteArray JNICALL Java_ramRead_MainClass_readRam
//(JNIEnv *env, jobject, jobject len, jobject addr, jint pid)
{
struct iovec local[1];
struct iovec remote[1];
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;
}
JNIEXPORT jint JNICALL Java_ramRead_MainClass_readSize
(JNIEnv *, jobject)
{
return nread;
}
到目前为止我已经尝试过:
检查 list 1.不是权限问题2. ram地址是正确的,我知道那里存储了什么。我怎么知道? 我正在读取计算器的 RAM,我正在寻找我输入的一组特定数字。使用 C++,我找到了它们,但使用 jni 却找不到。3. 阅读更多有关 UTF_8 和 UTF_16 的信息(问题很可能出在这里)4.看到这里的帖子试图重现解决方案,但无济于事。
操作系统:Linux 64 位 Fedora
问题:
如何将 C++ 字符串转换为 jstring,然后在 java 中将其返回并打印出来,以便输出与上面列出的 C++ 程序的输出匹配。
无论如何,这就是我打算解决它的方式,但如果有人有更好的解决方案或功能性解决方案,我会更乐意接受。
那么请大家付出时间和精力。
最佳答案
JNI 将字符串存储在 modified utf-8 encoding 中(见页面底部)。
如果你想继续使用字符串,那么你必须将你的字节转换成这种修改后的 utf-8 编码(所以字节值 >127 和零必须转换成 2 个字节)。
但正如 Jorn 在评论中建议的那样,您需要使用 ByteBuffer
或简单的字节数组 (byte[]
),因为它更优化:使用 String
会浪费内存,因为它包含 16 位元素。
关于java - 将字符串从 JNI (C++) 代码返回到 Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44782644/
到目前为止,我已经生成了以下代码来尝试将相关数据整合在一起。 但是,使用“+ 7”函数会产生以下问题。 Registration date = '2018-01-01' 它正在推迟 2018-04-0
我已经成功地将我的自定义购物车发布到 PayPal——它处理订单非常漂亮,当收到付款时,它会将数据发回我在配置中指定的 URL。代码基于此处找到的库:http://www.phpfour.com/bl
我是一名优秀的程序员,十分优秀!