开发者社区> 问答> 正文

JNI中调用任何标准输入输出处理流(std::stream)导致JVM崩溃? - jvm报错

大家好,我是JNI萌新!最近碰到一个很无解的问题,如标题所言。然后我也在Stackoverflow上搜索了一番,发现一个和我差不多的问题;但是解决办法对我没什么作用,我也在Stackoverflow上Post了自己的问题,一直在等待大神求解。可是过了这么多天,一直没什么反应,只好到这里来看看能不能找到一些好的办法!

 

下面是链接,不愿看英文(自己的英文也很差)的可以直接看代码:

http://stackoverflow.com/questions/43801055/how-to-convert-int-to-string-in-jni

 

问题简单的说就是在JNI中调用C++标准的流处理函数就会导致JVM崩溃,甚至连初始化都不行!Stackoverflow上类似的那个问题的解决办法对我无效,因为我是用Mac开发。对此有经验的大家请多多指教:

①这个问题产生的原因是什么?

②如果,使用std::stringstream解决不了问题,那有其他好的解决办法吗?(通过JNI把int数组中的元素转换为string类型,最好不需要返回参,即把传递进来的jint在JNI中直接转换)

展开
收起
montos 2020-05-31 21:18:50 753 0
1 条回答
写回答
取消 提交回答
  • crash之后,jvm打印出来的错误信息是什么,你的demo app运行在什么环境上?

    ######因为是JVM运行时错误,我对JNI不熟,也是需要用到它,最近才开始用。Logcat中没有错误日志,我也不知道该怎么去捕获这个错误信息。(app一启动就崩溃,logcat只提示JVM shutdown)我的app运行环境是华为P8实体机,不是虚拟机。######您好,我已经PO上代码了!######使用Java的char[]来去接受,在java中实现到String的转换。 JNI 没用过,这只是一种可能的方法。######

    样例代码:

    #include "utils_JniInterface.h"
    #include <android/log.h>
    #include <string.h>
    #include <iostream>
    #include <sstream>
    
    using namespace std;
    
    #define TAG "JNI-Log"
    #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
    
    JNIEXPORT jstring JNICALL Java_utils_JniInterface_constructRGBArrayString (JNIEnv *env, jobject obj, jintArray jArr){
        jint *arr = env -> GetIntArrayElements(jArr, 0);
        int len = env -> GetArrayLength(jArr);
    
        std::stringstream result;
    
        for(int i = 0; i < len; i++) {
            result << arr[i];
    
            if(i < len - 1) {
                result << ',';
            }
        }
    
        env -> ReleaseIntArrayElements(jArr, arr, 0);
    
        return env -> NewStringUTF(result.str().data());
    }
    
    // int[] a = {1,2,3} ⇒ String b = "1,2,3"

    鉴于,如果不能解决std::stringstream崩溃的问题,那希望可以通过JNI解决int到string转换的问题来达到我的需求。不太清楚我的需求的各位,我大致写一下代码的框架:

    int[] a = {1, 2, 3.....};需要通过转化的整型数组,通过JNI将里面的元素转化为string型;我的想法是这样,

    JNIEXPORT void JNICALL Java_utils_JniInterface_convertIntToString (JNIEnv *env, jobject obj, jintArray jArr){
        jint *arr = env -> GetIntArrayElements(jArr, 0);
        int len = env -> GetArrayLength(jArr);
    
        for(int i = 0; i < len; i++) {
           //遍历数组并一一就地转换
        }
    
        env -> ReleaseIntArrayElements(jArr, arr, 0);
    }
    
    ######回复 @frank_123 : 讲道理使用stringstream出问题是不应该的,我在PC机上写过类似代码,运行良好。如果不能解决这个问题,那就使用snprintf这类的函数来做,或者自己另外写一个函数来完成######回复 @GestureWei : 我明白你的意思了!那就不是编译库的问题产生的了,因为除了这个JNI函数之外,我还调用了其他JNI函数,这些函数主要做一些排序和筛选功能,运行完全没有问题!而是一旦牵扯到在JNI中做一些“流操作”,JVM就会崩溃!######首先你这个库的运行环境是手机上的,库编译需要用android ndk提供的工具链,这样出来的库才是能够在手机上运行。如果库不匹配或者找不到库,都会报出UnsatisfiedLinkError,而不是你这个jvm直接crash,所以还需要排查,你可以先写一个简单的求和函数,看看是否有问题######回复 @GestureWei : 不太明白!具体是什么意思?我搜过一些资料有说是Mac调用C++库很怪异的原因产生的,也有说是系统类型armv7,x86 64/32位等等不同产生的。您说的armv7库具体是指什么呢?我该怎么排查?######放在Android上跑应该也不会出现问题,这时候看看你的库是否是正确的编译的armv7库?######

    itos 可以吗?

    2020-06-01 09:47:35
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
JVM实战 立即下载
JVM的GC 立即下载
基于JVM的脚本语言开发、运用实践 立即下载