首页
学习
活动
专区
圈层
工具
发布

JNI编程
EN

Stack Overflow用户
提问于 2017-09-04 19:07:06
回答 2查看 359关注 0票数 0

我是jni编程的新手。我想把一个浮点数组从java传递给jni,在jni端动态分配足够的内存给浮点数组,在jfloatArray中存储一些值,然后在java中访问它。我不想返回jfloatArray,只需修改传入的浮点数组即可。我尝试了下面的方法,但它没有修改我的java浮动数组。如何做到这一点?

代码语言:javascript
复制
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中做到这一点

代码语言:javascript
复制
public class CustomObject{
  public  float[] points;
  public float[] getPoints() {
    return points;
  }

  public void setPoints(float[] points) {
    this.points = points;
  }

}
EN

回答 2

Stack Overflow用户

发布于 2017-09-04 19:28:17

看看JNI函数的第一行。

最初,pointListInPixels表示Java对象的地址- java代码中的float[] pointList

在下一行中,将其赋值给(env)->NewFloatArray,这意味着pointListInPixels不再指向float[] pointList,而是指向一个新的数组。因此,您对SetFloatArrayRegion的调用将不起作用。当然,它可以修改Java中的数组,但它不会修改您想要修改的数组。

这样做的正确方法是让您的JNI函数返回一个jFloatArray,将您的java代码转换为:

代码语言:javascript
复制
    float[] pointList = callJNIFunc();

和你的JNI代码:

代码语言:javascript
复制
    jFloatArray pointListInPixels = (env)->NewFloatArray(pointListSize.M * 2);
    env->SetFloatArrayRegion(pointListInPixels, 0, pointListSize.M * 2, pointFloats);
    return pointListInPixels;

方法签名应该根据需要进行更改。

票数 0
EN

Stack Overflow用户

发布于 2017-09-05 15:21:26

您可以创建容器类来返回值,如下所示:

代码语言:javascript
复制
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对象:

代码语言:javascript
复制
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对象的简单元加载器

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46035726

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档