ファイヤープロジェクト
フィールドの設定
2003-07-20T15:13+09:00   matsu
ネイティブコードからクラスやオブジェクトのフィールドを設定する.
フィールドの取得と設定の流れはほとんどが同じである.違いは値を設定するための関数である.やはりこの関数はインスタンスフィールドとスタティックフィールドで異なる.インスタンスフィールドの設定には,
void (JNICALL *Set<Type>Field)
      (JNIEnv *env, jobject obj, jfieldID fieldID, jint val);
で,スタティックフィールドの設定には,
void (JNICALL *SetStatic<Type>Field)
      (JNIEnv *env, jclass clazz, jfieldID fieldID, jint value);
である.例によって<Type>には設定するフィールドの型が入る.具体例はサンプルに示す.フィールドの設定の流れを以下に示す.
インスタンスフィールドの場合スタティックフィールドの場合
必要があればGetObjectClassでjclassを取得する
GetFieldIDでフィールドIDを取得GetStaticFieldIDでフィールドIDを取得
Set<Type>Fieldでフィールドの値を設定SetStatic<Type>Fieldでフィールドの値を設定
jclasやフィールドIDの取得はフィールドの取得の場合と同じである.
フィールドの取得で使用したサンプルの一部を修正して,フィールドを設定するサンプルを作成する.まず,問題のフィールドを保持するクラスは同じである.
そしてこのクラスのフィールドを設定するJavaクラスを作成する.
このクラスのネイティブメソッドからFieldsのフィールドを設定する.そのネイティブメソッドの実装を以下に示す.まずヘッダ.
そして関数本体.
当然ながら,設定対象となるオブジェクトへの参照を引数にとっている.実行結果を以下に示す.
publicFieldShort = 10
pkgPrivateFieldInt = 20
protectedFieldLong = 30
privateFieldDouble = 40.0
publicStaticFieldBoolean = false
pkgPrivateStaticFieldByte = 50
protectedStaticFieldChar = z
privateStaticFieldFloat = 60.0
SetterのメソッドからFieldsのフィールドが設定できた.
先のサンプルでは,別のオブジェクトにアクセスするネイティブメソッドがある.このサンプルにはJNIの凶暴な一面が含まれている.すなわちネイティブメソッドではフィールドやメソッドのアクセス修飾子に関係なくアクセスできる.Setterのネイティブメソッド内で,引数にとっているFieldsのインスタンスのプライベートメソッドを設定できてしまっている.しかもコンパイル時に警告すら発せられない.この凶暴な一面は常に念頭に置いておかなくてはなるまい.
matsu(C)
Since 2002
Mail to matsu