Sample Program (1)

1. コード

文字列 (java.lang.String) を、Java から JNI を通して Native Method に渡し、さらに SICStus Prolog に渡して表示させてみる。

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);
    initProlog();
  }

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

  static { System.loadLibrary("jcpl"); }
  public native void send(String data);
  public native void initProlog();

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

}

JNI を使用する以外は特別なところ無し。initProlog() は読んで字の如く SICStus の初期化を行なう (実際は cpl.c で初期化している)。

jc.c
#include <jni.h>
#include <stdio.h>
#include "Input.h"
#include "cpl.h"

JNIEXPORT void JNICALL
Java_Input_initProlog(JNIEnv *env, jobject obj)
{
  init();
}

JNIEXPORT void JNICALL 
Java_Input_send(JNIEnv *env, jobject obj, jstring data) 
{
  const char *str = (*env)->GetStringUTFChars(env, data, 0);
  printf("C       > %s\n", str); fflush(stdout);
  sendToPl(str);
  (*env)->ReleaseStringUTFChars(env, data, str);
  return ;
}
cpl.h
void init();
void sendToPl();
cpl.c
#include <stdio.h>
#include <sicstus/sicstus.h>

SP_pred_ref pred;
SP_term_ref data;
int         goal;

void init() {
  SP_initialize(0, NULL, NULL);
  SP_load("des.ql");
  pred = SP_predicate("send", 1, "");
  data = SP_new_term_ref();
}

void sendToPl(char *arg) {
  SP_put_string(data, arg);
  goal = SP_query(pred, data);
}

init() で SICStus の初期化を行なっている。

des.pl
send(Data) :-
	write('SICStus > '), write(Data), nl.

2. コンパイル

% javac Input.java
% javah -jni Input
% sicstus
SICStus 3 #5: Wed Oct 29 16:57:09 JST 1997
| ?- fcompile(des).
{fcompiling /home/yoshida/java/native/jpl/des.pl...}
{/home/yoshida/java/native/jpl/des.pl fcompiled, 10 msec 496 bytes}

yes
| ?- halt.
% spmkrs libjcpl.so +c jc.c cpl.c
SICStus 3  #5: Wed Oct 29 16:57:09 JST 1997
{/tmp/01312aaa.c generated, 0 msec}

yes
% ls
Input.class  Input.java   cpl.h        des.ql	    libjcpl.so*
Input.h      cpl.c	  des.pl       jc.c

3. 実行

実行すると入力用のウィンドウが現れ、打ち込んだ文字が Java、C、Prolog によって表示される。うーむ。

% java Input
Java    > yoshida
C       > yoshida
SICStus > yoshida
Java    > udraw
C       > udraw
SICStus > udraw