ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

JNI 中创建对象数组

2021-11-23 09:03:06  阅读:214  来源: 互联网

标签:JNIObjectArray Java env nullptr 创建对象 数组 JNI


JNI 中创建对象数组

在上一篇中介绍了JNI中创建对象。本文是JNI系列的第十篇,介绍JNI中的如何调在Native代码中创建对象数组。

系列文章的大纲如下:

JNI 中创建对象数组

创建对象数组很简单,一个函数就可以了,如下:

// 创建长度为length的类型为elementClass的数组,默认值为initialElement
jobjectArray NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement);

从数组中获取元素:

// 获取数组array中的第index个元素
jobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index);

更新数组中的元素:

// 将数组array的第index个元素设置为value
void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject value);

其他接口详见JNI 数组

通过下面的实例来加深一下理解。

实例

我们来看一个实例。

package myjni;

public class JNIObjectArray {
    static {
        System.loadLibrary("hello");
    }

    // Returns sum and average
    private native Double[] sumAndAverage(Integer[] numbers);

    public static void main(String[] args) {
        JNIObjectArray obj = new JNIObjectArray();
        Integer[] numbers = {2, 4, 5};
        Double[] results = obj.sumAndAverage(numbers);
        System.out.println("In Java, the sum is " + results[0]);
        System.out.println("In Java, the average is " + results[1]);
    }
}

如果还不清楚如果生成头文件请参考JNI简介

生成头文件myjni_JNIObjectArray.h的签名为:

/*
 * Class:     myjni_JNIObjectArray
 * Method:    sumAndAverage
 * Signature: ([Ljava/lang/Integer;)[Ljava/lang/Double;
 */
JNIEXPORT jobjectArray JNICALL Java_myjni_JNIObjectArray_sumAndAverage
  (JNIEnv *, jobject, jobjectArray);

实现函数Java_myjni_JNIObjectArray_sumAndAverage


JNIEXPORT jobjectArray JNICALL Java_myjni_JNIObjectArray_sumAndAverage(JNIEnv *env, jobject obj, jobjectArray array) {
  jclass classInteger = env->FindClass("java/lang/Integer");
  if (classInteger == nullptr) {
    std::cout << "find class java.lang.Integer failed\n";
    return nullptr;
  }

  jmethodID midIntValue = env->GetMethodID(classInteger, "intValue", "()I");
  if (midIntValue == nullptr) {
    std::cout << "get intValue() failed\n";
    return nullptr;
  }

  jsize length = env->GetArrayLength(array);
  jint sum = 0;
  for (int i = 0; i < length; i++) {
    jobject objInteger = env->GetObjectArrayElement(array, i);
    if (objInteger == nullptr) {
      std::cout << "get " << i << " element in array failed\n";
      return nullptr;
    }
    sum += env->CallIntMethod(objInteger, midIntValue);
  }

  double average = (double)sum / length;
  std::cout << "In C++, the sum is " << sum << "\n";
  std::cout << "In C++, the average is " << average << "\n";

  jclass classDouble = env->FindClass("java/lang/Double");
  if (classDouble == nullptr) {
    std::cout << "find class java.lang.Double failed\n";
    return nullptr;
  }

  jobjectArray resultArray = env->NewObjectArray(2, classDouble, nullptr);
  if (resultArray == nullptr) {
    std::cout << "create Double[] failed\n";
    return nullptr;
  }

  jmethodID midDoubleInit = env->GetMethodID(classDouble, "<init>", "(D)V");
  if (midDoubleInit == nullptr) {
    std::cout << "get Double.<init> failed\n";
    return nullptr;
  }

  jobject objSum = env->NewObject(classDouble, midDoubleInit, (double)sum);
  jobject objAvg = env->NewObject(classDouble, midDoubleInit, average);

  env->SetObjectArrayElement(resultArray, 0, objSum);
  env->SetObjectArrayElement(resultArray, 1, objAvg);

  return resultArray;
}

编译生成动态库,并运行Java程序得到输出:

In Java, the sum is 11.0
In Java, the average is 3.6666666666666665
In C++, the sum is 11
In C++, the average is 3.66667

vx搜:极客Furzoom,关注获取第一手资料。

本文完。

标签:JNIObjectArray,Java,env,nullptr,创建对象,数组,JNI
来源: https://blog.csdn.net/himayan46/article/details/121434240

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有