前回、NewStringUTF()で文字列を作って返した。
が、その前に考えていたのは違うことだった。
NewStringUTF()って、メモリを生成するから、どこかで解放せんといかんのでは?ということ。
解放しようとしても、そのときにはCを抜けたあとだ。
それじゃあ遅いよなあ。。。
ならば引数でバッファをもらって返すようにせんといかんよなぁ。。。
引数をバッファにするなら、StringBufferだろう。
package com.jnitest; import java.lang.StringBuffer; class Jni2 { public static void main(String[] args) { StringBuffer sb = new StringBuffer(); System.out.println("Hello"); getHelloString(sb); System.out.println(sb); } static { System.loadLibrary("jnihello"); } public static native void getHelloString(StringBuffer sb); } |
#include "com_jnitest_Jni2.h" JNIEXPORT void JNICALL Java_com_jnitest_Jni2_getHelloString (JNIEnv *env, jclass clazz, jobject jstrbuf) { jclass jcstrbuf = (*env)->GetObjectClass(env, jstrbuf); jmethodID mid = (*env)->GetMethodID(env, jcstrbuf, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;"); jstring js = (*env)->NewStringUTF(env, "Hello!"); (*env)->CallObjectMethod(env, jstrbuf, mid, 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には
- Void
- Object
- Boolean
- Byte
- Char
- Short
- Int
- Long
- Float
- Double
が入るとのこと。
CallNonvirtual<type>Methodというものもあるそうだ。
一度にやっても覚えないから、こっちは使うときでいいや。
<type>はどうやって選ぶかというと、戻り値でいいのかな。
引数は可変らしいので、必要なものをずらずら書けばいいのだろう。
まあ、なるべく使わずに済ませたいものだ。
0 件のコメント:
コメントを投稿
コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。
注: コメントを投稿できるのは、このブログのメンバーだけです。