JNIを使ってみる(2)〜Java→Jniオブジェクト渡し〜
k.tsuka
今回はJavaコード上で作成したオブジェクトをJNIで参照する方法について紹介します。

Javaコード上で生成したオブジェクトをJNIでも参照したい!という場面は、JNIを使用するアプリを作成する場合によく出てくる内容だと思いますが、Webサイトでちょこっと調べても良くわからないというのもよくある場面ではないでしょうか?
今回ご紹介する内容は、そんな場面で参考して頂ければと思います。

   ※JNIの基本的な使い方やそのサンプルについて、こちらに記事をアップしています。
     よろしければ、こちらも参照下さればと思います。

それでは、早速サンプルコードを見ていきましょう。

Java→JNIへ渡ったオブジェクトの値をJNIで参照する為に必要な手順は、以下の通りとなります。
○Javaソース

ここでは、Testクラスを引数に持つnativeメソッド(debug())を実行します。

public class TestJniActivity extends Activity {
    
    // Nativeメソッド
    private native void debug(Test o);
    
    /**
     * ライブラリロード
     */
    static {
        loadLib();
    }
    
    /**
     * JNIへInputするデータクラス
     */
    public class Test {
        int val;
    }
        
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        // JNIへInputするデータクラスを作成
        Test tes = new Test();
        // 作成したデータクラスのメンバ変数に値を設定
        tes.val = 123;
        
        // JNI実行
        debug(tes);    
    }
    
    
    /**
     * ライブラリロード
     */
    static void loadLib() {
        
        // Nativeライブラリをロード
        System.loadLibrary("hello-jni");
        
    }
}


○Cソース(JNIソース)

Javaコードから入力されたオブジェクトを参照して値を取得します。 ちなみに、JavaとNativeのインタフェースとなるクラスの第2引数【thiz】は、TestJniActivityオブジェクトへの参照(ポインタ)で、 【o】はTestオブジェクトへの参照となります。 つまりNativeメソッドにはオブジェクトの実態に対する参照が入力されることになります。
#include <stdio.h>
#include <jni.h>
#include <android/log.h>

#define LOG(...)    (__android_log_print(     \
                       ANDROID_LOG_DEBUG,     \
                       "testJNI",             \
                       __VA_ARGS__))

void Java_hoge_test_jni_TestJniActivity_debug(JNIEnv* env, 
                                              jobject thiz, 
                                              jobject o) {

    // クラス定義をロードする
    jobect clz2 = (*env)->GetObjectClass(env, o);
    
    // クラス定義から『val』のアクセスIDを取得する
    jfieldID field_id = (*env)->GetFieldID(env, clz2, "val", "I");
    
    // アクセスIDを用いて値をロードする
    jint value = (*env)->GetIntField(env, o, field_id);

    LOG("#### value = %d ####", value);
    
    return;
}

○makeファイル


LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := hello-jni
LOCAL_SRC_FILES := testjni_sample.c

LOCAL_LDLIBS := -llog

include $(BUILD_SHARED_LIBRARY)



参考にしたサイトおよび資料



inserted by FC2 system