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