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