LoginSignup
5
7

More than 5 years have passed since last update.

JNIからJavaの配列を操作する

Last updated at Posted at 2016-05-09

JNIメソッドから複数の戻り値を受け取りたい場合、ネイティブの構造体を直接Javaに受け渡すことはできないため、JNIでJavaオブジェクトを作成するか配列を使用して受け渡すことになります。

JNIでJavaオブジェクトを作成する方法は割と複雑でパフォーマンスを上げるためにキャッシュ処理をしたりしないといけないので面倒です。ベクトルや行列を扱う場合は配列を使うのが簡単なのでこの方法を紹介します。

次のようなJava APIを使って、ネイティブコードでJava配列に値を設定することを考える。

Java
package com.mycompany;

public class MyClass {
    private static native void putElements(float[] arr);
}

各要素を操作するには次のようにします。Get***ArrayElementsでポインタを取得して値を取得・代入して最後にRelease***ArrayElementsでポインタを開放します。***の部分はデータ型によって使い分けます。

JNI
JNIEXPORT void JNICALL
Java_com_mycompany_MyClass_putElements(JNIEnv * env, jclass clazz, jfloatArray arr) {
    jfloat *body = env->GetFloatArrayElements(arr, 0);
    body[0] = 1.23f;
    body[1] = 4.56f;
    body[2] = 7.89f;
    env->ReleaseFloatArrayElements(arr, body, 0);
}

Javaから渡された配列に入っている値をループで参照したい場合は、次のようにします。

JNI
JNIEXPORT void JNICALL
Java_com_mycompany_MyClass_iterateElements(JNIEnv * env, jclass clazz, jfloatArray arr) {
    jsize len = env->GetArrayLength(arr);
    jfloat *elements = env->GetFloatArrayElements(arr, 0);

    for (int i = 0; i < len; ++i) {
        float f = elements[i]; // 取得
        elements[i] = 3.1415f; // 設定
    }

    env->ReleaseFloatArrayElements(arr, elements, 0);
}
5
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
7