从 JNI (C++) 代码返回一个字符串到 Java

慢性用户

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++ 中的本机函数读取 ram 的内容,然后将其作为字符串或字符数组返回给 java 以进行进一步处理。

问题:

的返回值jstring result不是我在 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;
}

到目前为止我尝试过的:

检查清单 1. 不是权限问题 2. Ram 地址是正确的,我知道那里存储了什么。我怎么知道?我正在读取计算器的 RAM,我正在寻找我输入的一组特定数字。使用 C++ 我找到了它们,但实际上不是 jni。3. 阅读有关 UTF_8 和 UTF_16 的更多信息(问题很可能出在这里) 4. 在这里看到的帖子试图重现解决方案,但无济于事。

操作系统:Linux 64 位 Fedora

问题:

如何将 C++ 字符串转换为 jstring,然后在 java 中返回它并打印出来,以便输出与上面列出的 C++ 程序的输出匹配。

无论如何,这就是我打算解决它的方式,但是如果有人有更好的解决方案或只是功能性解决方案,我会更乐意接受它们。

那么你们都为你的时间和努力。

格萨

JNI 以修改后的 utf-8 编码存储字符串(参见页面底部)。

如果您想继续使用字符串,那么您必须将您的字节转换为这种修改后的 utf-8 编码(因此字节值 >127 和零必须转换为 2 个字节)。

但正如 Jorn 在评论中所建议的,您将希望使用ByteBuffer或 一个简单的字节数组 ( byte[]) ,因为它更优化:使用String,您会浪费内存,因为它包含 16 位元素。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

JNI将一个字符串从java传递给c++,然后将c++字符串传递给字符串数组

来自分类Dev

使用JNI将字符串从Java传递到C ++

来自分类Dev

获取从Java到C ++ JNI的字符串数组

来自分类Dev

获取从Java到C ++ JNI的字符串数组

来自分类Dev

如何返回从Java流只是一个字符串

来自分类Dev

将图像从c ++传递给Haskell并返回一个字符串

来自分类Dev

从C中的函数返回一个字符串

来自分类Dev

让C从main返回一个字符串

来自分类Dev

Objective-C在NSURLSessionDataTask中返回一个字符串

来自分类Dev

GetDirectories给我返回了一个字符串C#

来自分类Dev

从 C 中的 if 语句返回一个字符串

来自分类Dev

C ++每X个字符分割一个字符串

来自分类Dev

JNI 从 Java 到 C++ 的转换

来自分类Dev

使用十六进制代码从java字符串中删除一个字符

来自分类Dev

如何使用2个字符串参数从jni java库调用?

来自分类Dev

将多个字符串读为一个字符串?C ++

来自分类Dev

C#操纵一个字符串作为十六进制代码?

来自分类Dev

转义 JNI 代码的 Java 字符串

来自分类Dev

C#教程,如何在方法中返回一个字符串?

来自分类Dev

如何确定一个字符串部分地包含另一个字符串?(最好是Java)

来自分类Dev

替换一个字符串,只要它在Java中不被另一个字符串跟随?

来自分类Dev

Java / XML:在另一个字符串中使用一个字符串

来自分类Dev

Java使用嵌套循环在另一个字符串中查找一个字符串出现的次数

来自分类Dev

JAVA:方法,一个字符串在另一个字符串中出现多少次

来自分类Dev

Java检查另一个字符串中的一个字符串

来自分类Dev

检查一个字符串是否在C ++中是另一个字符串的排列

来自分类Dev

使用C ++将一个字符串替换为另一个字符串

来自分类Dev

用前一个字符在Java中拆分字符串

来自分类Dev

Java获取字符串的第一个字符值

Related 相关文章

  1. 1

    JNI将一个字符串从java传递给c++,然后将c++字符串传递给字符串数组

  2. 2

    使用JNI将字符串从Java传递到C ++

  3. 3

    获取从Java到C ++ JNI的字符串数组

  4. 4

    获取从Java到C ++ JNI的字符串数组

  5. 5

    如何返回从Java流只是一个字符串

  6. 6

    将图像从c ++传递给Haskell并返回一个字符串

  7. 7

    从C中的函数返回一个字符串

  8. 8

    让C从main返回一个字符串

  9. 9

    Objective-C在NSURLSessionDataTask中返回一个字符串

  10. 10

    GetDirectories给我返回了一个字符串C#

  11. 11

    从 C 中的 if 语句返回一个字符串

  12. 12

    C ++每X个字符分割一个字符串

  13. 13

    JNI 从 Java 到 C++ 的转换

  14. 14

    使用十六进制代码从java字符串中删除一个字符

  15. 15

    如何使用2个字符串参数从jni java库调用?

  16. 16

    将多个字符串读为一个字符串?C ++

  17. 17

    C#操纵一个字符串作为十六进制代码?

  18. 18

    转义 JNI 代码的 Java 字符串

  19. 19

    C#教程,如何在方法中返回一个字符串?

  20. 20

    如何确定一个字符串部分地包含另一个字符串?(最好是Java)

  21. 21

    替换一个字符串,只要它在Java中不被另一个字符串跟随?

  22. 22

    Java / XML:在另一个字符串中使用一个字符串

  23. 23

    Java使用嵌套循环在另一个字符串中查找一个字符串出现的次数

  24. 24

    JAVA:方法,一个字符串在另一个字符串中出现多少次

  25. 25

    Java检查另一个字符串中的一个字符串

  26. 26

    检查一个字符串是否在C ++中是另一个字符串的排列

  27. 27

    使用C ++将一个字符串替换为另一个字符串

  28. 28

    用前一个字符在Java中拆分字符串

  29. 29

    Java获取字符串的第一个字符值

热门标签

归档