我是jni编程的新手。我想把一个浮点数组从java传递给jni,在jni端动态分配足够的内存给浮点数组,在jfloatArray中存储一些值,然后在java中访问它。我不想返回jfloatArray,只需修改传入的浮点数组即可。我尝试了下面的方法,但它没有修改我的java浮动数组。如何做到这一点?
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上读到,这可以通过传递一个自定义对象来实现。但是,对于包含这样的浮动数组的java对象,我不太确定如何在jni中做到这一点
public class CustomObject{
public float[] points;
public float[] getPoints() {
return points;
}
public void setPoints(float[] points) {
this.points = points;
}
}发布于 2017-09-04 19:28:17
看看JNI函数的第一行。
最初,pointListInPixels表示Java对象的地址- java代码中的float[] pointList。
在下一行中,将其赋值给(env)->NewFloatArray,这意味着pointListInPixels不再指向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;方法签名应该根据需要进行更改。
发布于 2017-09-05 15:21:26
您可以创建容器类来返回值,如下所示:
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 heap内)创建。您可以使用这个code snippet中的java对象的简单元加载器
https://stackoverflow.com/questions/46035726
复制相似问题