我是jni编程的新手。我想将一个float数组从java传递给jni,动态分配足够的内存到jni端的float数组,在jfloatArray中存储一些值,并在java中访问它。我不想返回jfloatArray,只需修改传递的输入float数组。我尝试了下面的方法,但它没有修改我的java float数组。怎么做到这一点?
Java Code:
float[] pointList = null;
outputBitmap = callJNIFunc(pointList, inputBitmap);
JNI Code:
Bitmap callJNIFunc(JNIEnv *env, jfloatArray pointListInPixels, jobject inputBitmap) {
pointListInPixels = (env)->NewFloatArray(pointListSize.M * 2);
env->SetFloatArrayRegion(pointListInPixels, 0, pointListSize.M * 2, pointFloats);
}
我从pass data between Java and C读到这可以通过传递自定义对象来实现。但是,我不太确定如何从jni中为包含像这个
的float数组的java对象这样做public class CustomObject{
public float[] points;
public float[] getPoints() {
return points;
}
public void setPoints(float[] points) {
this.points = points;
}
}
答案 0 :(得分:0)
查看JNI函数的第一行。
最初,pointListInPixels
表示Java对象的地址 - 您的java代码中的float[] pointList
。
在下一行中,您将其分配给(env)->NewFloatArray
,这意味着pointListInPixels
不再指向Java中的float[] pointList
,而是指向新数组。因此,您对SetFloatArrayRegion
的通话无效。它确实用Java修改了一个数组,但是它并没有修改你想要它修改的数组。
这样做的正确方法是让你的JNI函数返回jFloatArray
,将你的java代码转换为:
float[] pointList = callJNIFunc();
和您的JNI代码:
jFloatArray pointListInPixels = (env)->NewFloatArray(pointListSize.M * 2);
env->SetFloatArrayRegion(pointListInPixels, 0, pointListSize.M * 2, pointFloats);
return pointListInPixels;
应根据需要更改方法签名。
答案 1 :(得分:0)
您可以创建容器类来返回值,如下所示:
public class Result{
public final Bitmap bitmap;
public final float[] pointListInPixels;
public Result(Bitmap bitmap, float[] pointListInPixels){
this.bitmap = bitmap;
this.pointListInPixels = pointListInPixels;
}
}
从jni构造并返回Result
对象:
Result callJNIFunc(JNIEnv *env, jfloatArray pointListInPixels, jobject inputBitmap) {
// load class by name
jclass cls = env->FindClass("my/package/name/Result");
if (env->ExceptionOccurred()) return NULL;
// take constructor by signature
jmethodID constructorId = env->GetMethodID(cls, "<init>", "(android/graphics/Bitmap, [[F)V");
if (env->ExceptionOccurred()) return NULL;
jobject output_bitmap; // create bitmap and implement logic
pointListInPixels = (env)->NewFloatArray(pointListSize.M * 2);
env->SetFloatArrayRegion(pointListInPixels, 0, pointListSize.M * 2, pointFloats);
// create result object
jobject result = env->NewObject(cls, constructorId, output_bitmap, pointListInPixels);
return result;
}
对于此代码示例,您不需要delete
对象,因为它们将由java api(在Java堆内部)创建。您可以使用简单元加载器来处理来自此code snippet