I've started writing a J to Java interface and realized the following
steps needed to be implemented:
- Create C wrapper functions to expose J methods through JNI.
- Create a Java wrapper class to call those JNI methods.

Then, the methods of the wrapper class should be called in the following order:
- JInit - creates the J instance
- J method(s)
- JFree - destroys the J instance (no more methods are going to be called).


So, in order to call "JDo", I had to write the following code:
=== C code =============================================================
#include "j_jwrapper.h"
#include <windows.h>
BOOL APIENTRY DllMain(HANDLE hInst, DWORD reason, LPVOID reserved){
return TRUE; }

#define JCALL(Method) long (CALLBACK* j_##Method)

JCALL(Init)(void);
JCALL(Free)(long jh);
JCALL(Do)(long jh, const char *cmd);

HMODULE jdll= NULL;

JNIEXPORT jint JNICALL Java_j_JWrapper_JInit(JNIEnv *env, jobject this)
{
       jdll = LoadLibrary("j.dll");
       if (!jdll)
               return 0;
       *(FARPROC*)&j_Init = GetProcAddress(jdll, "JInit");
       *(FARPROC*)&j_Free = GetProcAddress(jdll, "JFree");
       *(FARPROC*)&j_Do = GetProcAddress(jdll, "JDo");
       return j_Init();
}

JNIEXPORT jint JNICALL Java_j_JWrapper_JDo(JNIEnv *env, jobject this,
jint j, jstring cmd)
{
       const char *pcmd = (*env)->GetStringUTFChars(env, cmd, JNI_FALSE);
       jint ec = jdll_Do(j, pcmd);
       (*env)->ReleaseStringUTFChars(env, cmd, pcmd);
       return ec;
}

JNIEXPORT jint JNICALL Java_j_JWrapper_JFree(JNIEnv *env, jobject this, jint jh)
{
       jint ec = j_Free(jh);
       FreeLibrary(jdll);
       return ec;
}

=== Java wrapper =======================================================
package j;

public class JWrapper {
       private int jh = 0;
       static {System.loadLibrary("JayJNI");}

       native int JInit();
       native int JFree(int jh);
       native int JDo(int jh, String cmd);

       public JWrapper() {}

       public Init() throws Exception {
               jh = JInit();
               if (jh == 0) { throw new Exception("J DLL could not be
loaded."); }
       }

       public int Free() {
               return JFree(jh);
       }

       public void Do(String cmd) throws Exception {
               int ec = JDo(jh, cmd);
               if (ec != 0) { throw new Exception("JDo failed with
code: "+ec); }
       }
}

=== Usage ==============================================================
JWrapper J = new JWrapper();
J.Init();
J.Do("'hello'(1!:2)<'out.txt'");
J.Free();
========================================================================

It seems difficult that there isn't a Java API available, considering
there is a Java front-end to J. Do we really need to write this kind
of code, or am I missing something?
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to