2011/03/26

[java]引数で文字列を返してみる

前回、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 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。

注: コメントを投稿できるのは、このブログのメンバーだけです。