-1

我只是跟着这篇文章。现在,我有了这个 JNI 代码:

extern "C"{
   JNIEXPORT jfloatArray JNICALL Java_com_jp_algi_Corelib_vector
       (JNIEnv *env, jobject clazz, jfloatArray input){
        jfloat* flt1;
        flt1  = (*env)->GetFloatArrayElements(env, input, NULL);
        if (flt1 == NULL){
            return NULL; /* exception occurred */
        }
        // do stuff to the array
        (*env)->ReleaseFloatArrayElements(env, input, flt1, 0);
        return flt1;
        //delete flt1, v;
        //env->SetFloatArrayRegion(result, 0, 1, v);
    }
}

并检查它是否正常;我在 Java 代码数组中有长度检查以记录,它仍然发回 44 512 数组,并且不受输入数组长度的影响!它仍然一样,我认为我的 中有一些错误Application.mk,因为构建它的 OK

App.mk

  APP_ABI := all
  APP_STL := stlport_static

并且andr.mk可以肯定:

LOCAL_PATH := $(TOP_LOCAL_PATH)
include $(CLEAR_VARS)
LOCAL_MODULE    := com_jp_algi_Corelib
LOCAL_SRC_FILES := com_jp_algi_Corelib.cpp, kiss_fft.c, kiss_fftr.c
include $(BUILD_SHARED_LIBRARY)

好的,我的问题是:

我的 JNI 代码不起作用,我不知道为什么,因为我不懂 JNI 和 C++!

请有人告诉我如何重写我的代码?

好的,我的任务是:

  • 我想让 Java 数组到 C++ 只使用数组并返回到 Java 数组
4

1 回答 1

2

起初,您不能将 jfloat* 返回给 Java。你很幸运,这段代码不会使 JVM 崩溃。其次,在调用 ReleaseFloatArrayElements 后,您不能使用指向数组的指针(我的意思是 jfloat*),因为您将此数组返回给 JVM,它可以移动它甚至删除

更新 ACORDING 任务

通常我是这样做的。

extern "C" {
JNIEXPORT jboolean JNICALL Java_com_jp_algi_Corelib_vector
   (JNIEnv *env, jobject clazz, jfloatArray input){
    jfloat* flt1 = NULL;
    jsize size = env->GetArrayLength(input);
    // check if array size >0 and wedont cause exception
    if(size<=0) return(JNI_FALSE);
    if(env->ExceptionCheck()) {
#ifndef NDEBUG
      env->ExceptionDescribe();
#endif
      env->ExceptionClear();
      return(JNI_FALSE);
    }
    // allocate buffer for array and get data from Java array
    flt1  = new jfloat[size];
    env->GetFloatArrayRegion(input,0,size,flt1);
    // exception check. Always use exception check
    if(env->ExceptionCheck()) {
#ifndef NDEBUG
      env->ExceptionDescribe();
#endif
      env->ExceptionClear();
      delete[] flt1;
      return(JNI_FALSE);
    }
    // do stuff to the array
    // set result to Java array and delete buffer. And exception check of course
    env->SetFloatArrayRegion(input,0,size,flt1);
    delete[] flt1;
    if(env->ExceptionCheck()) {
#ifndef NDEBUG
      env->ExceptionDescribe();
#endif
      env->ExceptionClear();
      return(JNI_FALSE);
    }
    // All is ok
    return(JNI_TRUE);
}
}

最好使用 GetArrayRegions/SetArrayRegion,因为当您使用 GetFloatArrayElements 时,您会阻止原始 java 数组在内存中移动。在某些情况下,如果有一些,它可能会在其他线程中导致 OutOfMemoryException

PS:我不确定我没有错过一些括号,如果是这样,对不起

于 2013-01-11T15:54:20.480 回答