javahで生成された関数プロトタイプは以下の様でした。
JNIEXPORT void JNICALL
Java_jp_sprix_jni_ImageRecognize_queryImage(JNIEnv *env, jobject obj){
…
すべての関数プロトタイプは JNIEnvポインタ が最初の引数として宣言されます。
C++ネイティブコードは、JNIEnvポインタ で自分のメソッド(this)と同じように使うことができます。C++オブジェクトは、同様の方法で自分自身のメソッドへのポインタを保持しているので、このように使うことができます。
では、Javaのデータフィールドを操作してみましょう。
オブジェクトのデータフィールドにネイティブからアクセスする
以下のようなJavaコードがあったとしましょう。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class ImageRecognize { | |
private int mMajarVersion = 1; | |
protected int mMinorVersion = 9; | |
private static int mRevision = 980; | |
public void printVersion() { | |
System.err.println("Version: " + mMajarVersion + "." + mMinorVersion + "_" + mRevision); | |
} | |
public native void setMMajarVersion(int val); | |
public native void setMRevision(int val); | |
} |
それぞれの値をsetするnativeメソッドを作っておきましょう。
javahで生成した関数プロトタイプが以下です。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Class: jp_sprix_jni_ImageRecognize | |
* Method: setMMajarVersion | |
* Signature: (I)V | |
*/ | |
JNIEXPORT void JNICALL Java_jp_sprix_jni_ImageRecognize_setMMajarVersion | |
(JNIEnv *, jobject, jint); | |
/* | |
* Class: jp_sprix_jni_ImageRecognize | |
* Method: setMRevision | |
* Signature: (I)V | |
*/ | |
JNIEXPORT void JNICALL Java_jp_sprix_jni_ImageRecognize_setMRevision | |
(JNIEnv *, jobject, jint); |
関数プロトタイプの実装は以下のようにできます。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
JNIEXPORT void JNICALL | |
Java_jp_sprix_jni_ImageRecognize_setMMajarVersion(JNIEnv *env, jobject thisObj, jint val){ | |
jclass clazz = env->GetObjectClass(thisObj); | |
jfieldID fid = env->GetFieldID(clazz, "mMajarVersion", "I"); | |
env->SetIntField(thisObj, fid, val); | |
} | |
JNIEXPORT void JNICALL | |
Java_jp_sprix_jni_ImageRecognize_setMRevision(JNIEnv *env, jobject thisObj, jint val){ | |
jclass clazz = env->GetObjectClass(thisObj); | |
jfieldID fid = env->GetStaticFieldID(clazz, "mRevision", "I"); | |
env->SetStaticIntField(clazz, fid, val); | |
} |
これらからわかることを整理してみましょう。
- staticとそうでないデータフィールドにアクセスするには、それぞれ違い関数集合がある
- staticなデータフィールドを参照する場合、jclass への参照が必要
- 非静的なデータフィールドを参照する場合、jobject への参照が必要
- データフィールドを操作するJNI関数は、アクセスするデータ型を名前に含む
次は、Javaオブジェクトのデータフィールドを取得してみましょう。
0 件のコメント:
コメントを投稿