Sample Program (1)

取り敢えず、ここまで覚えたことを使って、サンプルプログラムです。

1. コード

Input.java
import java.awt.*;
import java.awt.event.*;

public class Input extends Panel implements ActionListener{

  TextField tf;

  public Input() {
    tf = new TextField(30);
    tf.addActionListener(this);
    setLayout(new BorderLayout());
    add("Center", tf);
  }

  public void actionPerformed(ActionEvent e) {
    if (e.getSource() == tf) {
      String str = tf.getText();
      System.out.println("Java> "+str);
      int length = send(str);
      System.out.println("length = "+length);
      tf.setText("");
    }
  }

  static { System.loadLibrary("input"); }
  public native int send(String data);

  public static void main(String args[]) {
    Frame f = new Frame();
    Input i = new Input();
    f.add("Center", i);
    f.pack();
    f.show();
  }

}
Input.c
#include <jni.h>
#include "Input.h"
#include <stdio.h>

JNIEXPORT jint JNICALL 
Java_Input_send(JNIEnv *env, jobject obj, jstring data) 
{
  /*dataのクラス(java.lang.String)を取得*/
  jclass cls = (*env)->GetObjectClass(env, data);
  /*String.length() の MethodID を取得*/
  jmethodID mid = (*env)->GetMethodID(env, cls, "length", "()I");
  int length;

  const char *str = (*env)->GetStringUTFChars(env, data, 0);
  printf("C   > %s : ", str); fflush(stdout);
  /* nativeからjava.lang.String.length()をコールする */
  length = (*env)->CallIntMethod(env, data, mid);
  (*env)->ReleaseStringUTFChars(env, data, str);
  return length;
}

Java で入力用ウィンドウを開き、入力した文字列を C に渡して、C から java.lang.String.length() を呼んで文字列の長さを求めて、求められた長さを Java に返す、という面倒なことをしています。

java.lang.String.length() は、引数無し、返値は int なので、Type Signature は "()I" になります。

2. 実行

% java Input

として実行すると、次のようなウィンドウが開き、文字を入力すると、その長さを調べて、標準出力に表示する。

Java> YOSHIDA
C   > YOSHIDA : length = 7
Java> NORISHIGE
C   > NORISHIGE : length = 9
Java> hogehoge
C   > hogehoge : length = 8
Java> Java Native Method Interface : JNI
C   > Java Native Method Interface : JNI : length = 34