【问题标题】:C++ and JNI - How to pass an array into a jfloatArrayC++ 和 JNI - 如何将数组传递到 jfloatArray
【发布时间】:2012-01-22 10:00:05
【问题描述】:

我一直在搞乱我自己的小项目,用 c++ 和 jni 自学 android ndk,但我不知道如何将数据从 java 浮点数组传递到 c++ 数组。我已经使用了 jni 设置。我发现的大多数教程要么太简单,解释不够,要么太复杂,暂时超出了我的理解。所以,有人能指出一个简单的例子,一个数组从java传递到c++,然后对数据执行一些方法/函数并发送回java。

这是我迄今为止的尝试,但我还有两个错误。我不确定其余的语法是否符合标准,但我在编译时看不到任何东西。

#include <iostream>
#include <Eigen/Dense>
#include <math.h>
#include <jni.h>

using namespace Eigen;

Vector3f vec;
Vector3f vec2;
Vector3f vecRtrn;


void vecLoad(float x, float y, float z, float x2, float y2, float z2){

vec(0) = x;
vec(1) = y;
vec(2) = z;
vec2(0) = x2;
vec2(1) = y2;
vec2(2) = z2;

}

void vecAdd(Vector3f vecA, Vector3f vecB){
vecRtrn = vecA+vecB;
}

extern "C"
{
JNIEXPORT jfloatArray JNICALL Java_jnimath_act_JnimathActivity_test
(JNIEnv *env, jobject obj, jfloatArray fltarray1, jfloatArray fltarray2){

float array1[3];

jfloatArray flt1 = fltarray1;
jfloatArray flt2 = fltarray2;

//flt1 = env->GetFloatArrayElements( fltarray1,0);
//flt2 = env->GetFloatArrayElements( fltarray2,0);


vecLoad(flt1[0], flt1[1], flt1[2], flt2[0], flt2[1], flt2[2]);
vecAdd(vec, vec2);

array1[0] = vecRtrn[0];
array1[1] = vecRtrn[1];
array1[2] = vecRtrn[2];

return array1;

};
}

这些是编译时的错误

 $ /cygdrive/c/android-ndk-r7/ndk-build
Compile++ thumb  : test <= test.cpp
jni/test.cpp: In function '_jfloatArray* Java_jnimath_act_JnimathActivity_test(JNIEnv*,    _jobject*, _jfloatArray*, _jfloatArray*)':
jni/test.cpp:42: error: cannot convert '_jfloatArray' to 'float' for argument '1' to      'void vecLoad(float, float, float, float, float, float)'
jni/test.cpp:49: error: cannot convert 'float*' to '_jfloatArray*' in return
make: *** [obj/local/armeabi/objs/test/test.o] Error 1

【问题讨论】:

    标签: android c++ arrays java-native-interface


    【解决方案1】:

    首先你不能直接使用 jfloatArray。相反,你应该这样做

    JNIEXPORT jfloatArray JNICALL Java_jnimath_act_JnimathActivity_test
    (JNIEnv *env, jobject obj, jfloatArray fltarray1, jfloatArray fltarray2)
    {
    
    jfloatArray result;
     result = env->NewFloatArray(3);
     if (result == NULL) {
         return NULL; /* out of memory error thrown */
     }
    
    jfloat array1[3];
    jfloat* flt1 = env->GetFloatArrayElements( fltarray1,0);
    jfloat* flt2 = env->GetFloatArrayElements( fltarray2,0);
    
    
    vecLoad(flt1[0], flt1[1], flt1[2], flt2[0], flt2[1], flt2[2]);
    vecAdd(vec, vec2);
    
    array1[0] = vecRtrn[0];
    array1[1] = vecRtrn[1];
    array1[2] = vecRtrn[2];
    
    env->ReleaseFloatArrayElements(fltarray1, flt1, 0);
    env->ReleaseFloatArrayElements(fltarray2, flt2, 0);
    env->SetFloatArrayRegion(result, 0, 3, array1);
    return result;
    
    }
    

    请将此作为教程并进行更多学习。正如我之前所说,此时学习对你的帮助比练习更多。

    【讨论】:

    • 嘿,谢谢保罗.....如果这得到了我正在工作的简单 jni 测试应用程序,请确保将其与所有来源一起发布在这里 :)
    • 嘿,这是我想出的解决方案,感谢您的帮助 :) stackoverflow.com/questions/8543221/…
    【解决方案2】:

    这基本上足以用新的 ndks 创建一个空数组。假设 env 是你的 jni 环境。

    jfloatArray jArray = env -> NewFloatArray(8);
    

    【讨论】:

      【解决方案3】:
      validateAudio(JNIEnv* env, jobject obj, jstring resourceFolderPath, ,jfloatArray thresholdArray){
          const char *resource_folder_path = (*env)->GetStringUTFChars(env,resourceFolderPath,0); // string parameter
          const jfloat* threshold_array = (*env)->GetFloatArrayElements(env, thresholdArray,0);  //float array
      }
      

      【讨论】:

        【解决方案4】:

        现在我们应该这样做:

        jfloatArray result;
        result = (*env)->NewFloatArray( env, numbers_here );
        

        【讨论】:

        • “numbers_here”的确切语法是什么?大括号?副药?逗号分隔的参数?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-08
        • 1970-01-01
        • 1970-01-01
        • 2015-11-06
        相关资源
        最近更新 更多