blog画像が表示されないページは、元画像を間違えて削除してしまっているためです。データが残っていないので、想像力で補ってください。2011/03/27[java]JNIからのコールバックコールバックといえども、関数呼び出しに代わりはなかろう。関数というか、メソッド呼び出し。考えると、StringBuffer.append()を呼び出したようなしくみでいいはず。自分一人で解決できたように書いているが、そんなことはない。bitlogさんの記事を見て、ようやくできた。com.jnitest.JniHellocallbackよくわかってないのが、なぜCallVoidMethod()するのにjobjectが必要なのかということ。NewObject()しているから、これはJava_com_jnitest_Jni_callCallback()を呼び出した人とは別の人になっていると思う。引数のclazzから取ってくることはできないのかな?まず、jcを取り除き、clazzに置き換える・・・よし、動いた。あれ、jclassからオブジェクトを取ってくる関数はないな。nativeって書いとるやん。コールバックして呼び出そうとする方は非staticだ。これがいかんのですな。そんなわけで、コールバックする方もstaticにするか、nativeを非staticにするか、だ。今回はmain()から呼び出すので、コールバックする方をstaticにした。Java[android]JNIHelpAndroidのソースを見ていると、javahが生成したような関数名のものもあるが、そうではないものもある。ないものはどうやっているのか気になっていたのだが、JNIからのコールバック関連を調べていて少しわかった。RegisterNatives()というJNI用関数がある。これは、ネイティブメソッドの登録らしい。Javaに書いたnative付きの関数と、C/C++で書いた関数を動的に結びつけるのであろう。AndroidのJNIHelpには、jniRegisterNativeMethods()という関数がある。これは、FindClass()とRegisterNatives()、その後片付けをやってくれる。Java[nfc]規格の関係NFC関係の規格はいろいろとあって、なにがなんだかわかりづらい。自分のイメージを図にしてみた。これはこれでわかりづらい。15693が浮いているのは、私がよくわかっていないから。nfc[java]Cからコールバックしたい(考察編)まだ考えている段階で、調査してない。今回Javaを調べ始めたのも、元はといえばJNIで呼び出した先からコールバックしたいというだけのことだ。私の思うコールバック(Javaではない)は、自分の関数を相手から呼び出してもらう、だ。電話の「かけ直してください」だ。電話だと、相手が誰からなのかは固定されていない。固定された相手だったら単なる関数呼び出しなのだが、不定なので「かけ直してください」という登録が必要になる。呼び出してもらう関数を登録するところから呼び出しするまでが「コールバック」としてよいだろう。C/C++ならば、引数でアドレスを教えてもらって保持するだけだ。コールも、そのアドレスを呼び出すだけ。実にシンプルで、私にとってはわかりやすい。わかりやすいが、安全ではない。アドレス/ポインタでC/C++でチェックできるのは、NULLかどうかくらいしかない。無効なポインタかどうかのチェックはできない。inlineとかになると、関数になるかどうかすら確定してない。「書いたコード以上のことはしない」というスタイル。JNIもC/C++だから、Objectでメソッドのアドレスとコンテキストをもらえば何とかなるかな、と思っていたけれども、リフレクションの話を聞いていて、そんな簡単では済まないと感じた。JavaVMを介して呼び出すようにしないと、呼び出せないだろうという感触だ。高速だけど何かあったら即死するC/C++、死んでもJavaVMが管理してくれるJava、というところか。いつもC/C++でしかコードを書かないけれども、一番気を配らないといけないのは死なないようにすることで、それが一番難しいし時間もかかる。想定する範囲外でなにか起こったら対処できないし。「安全」のためには、そういう言語がいいのだろうな、と改めて思った。OSの類が動ける環境でなくても使えるC/C++が好き、ということには変わりないがね。いいところはいいと認める心の余裕はあるのだ。あとは勉強が足りないのを何とかせんと・・・。Java[java]リフレクションに似ているらしい前回、Call<type>Method()でBufferString.append()を呼び出した。リフレクション、も同じような使い方らしい。残念なことに、リフレクションについての書籍を持たない。いくつかネットで見てみたところからすると、JavaのリフレクションというのはAPIを文字列で使えるしくみ、ということでいいのかな?いや、まだ奥があるらしい。さんに教えてもらったのだが、リフレクションはメタデータを扱うしくみらしい。多階層とかそんな意味だよな、メタって。第1回:クラスとクラスのロード処理」。ここから先を読んでいけば、私のほしい情報が手に入りそうだ。今日はもう酔っ払いなのでやめておくが、ToDoリストに追加しておこう。Java2011/03/26[java]引数で文字列を返してみる前回、NewStringUTF()で文字列を作って返した。その前に考えていたのは違うことだった。NewStringUTF()って、メモリを生成するから、どこかで解放せんといかんのでは?ということ。解放しようとしても、そのときにはCを抜けたあとだ。それじゃあ遅いよなあ。引数でバッファをもらって返すようにせんといかんよなぁ。引数をバッファにするなら、StringBufferだろう。js);}参考にしながら作ってみた。これでちゃんと"Hello!"返してくれた。何しているのか考えてみた。StringBufferのクラスを取ってくる。GetMethodID()でStringBuffer.append()のIDを取ってくる。最後にCallObjectMethod()にIDを渡すと、CからStringBuffer.append()を呼び出すことができるのだろう。StringBuffer.append()ってどういう関数か知らずに使ったけど、引数1つなんだな。"(Ljava/lang/String;)Ljava/lang/StringBuffer;"これは、java.lang.StringBuffer.append(java.lang.String)を使うという意味であろう。CallObjectMethod()ですな。Call<type>Method()という形で、typeにはVoidObjectBooleanByteCharShortIntLongFloatDoubleが入るとのこと。CallNonvirtual<type>Methodというものもあるそうだ。一度にやっても覚えないから、こっちは使うときでいいや。<type>はどうやって選ぶかというと、戻り値でいいのかな。引数は可変らしいので、必要なものをずらずら書けばいいのだろう。使わずに済ませたいものだ。Java[java]cygwinでのJNIにはgcc-3を使うとよいのかこうコンパイルした。com_jnitest_Jni2.c動いた・・・。no-cygwinがいるみたいだ。-mno-cygwinを付けてコンパイルするには、gcc-4ではなくgcc-3にする必要がある。これで逃げられるなら、それでいいか。Java[java]gcjが動かないもしかすると、JDKを使っているからだめなのか?cygwinだから、gcjを使うといいんではなかろうか。Source)だめだねぇ。Java[java]cygwinでのJNIがうまくいかん2回目にしてよくわからん。helloString();}こんなのだ。com.jnitest.Jni2com_jnitest_Jni2.hというヘッダファイルができる。これを使ってCソースを書く。!";}まあこんなもんだろう。