changeset 22:4ee8d6aa7721

- java binding cleanup, exposed free functions (not very oo, this entire binding) - java binding examples
author cslag
date Sat, 09 Apr 2016 18:18:34 -0500
parents 40a2c4198016
children 87fd9f34eaa0
files java/jdc/Makefile java/jdc/examples/UnixLibCExample.java java/jdc/examples/UnixMathExample.java java/jdc/org/dyncall/DC.java java/jdc/org_dyncall_DC.c
diffstat 5 files changed, 120 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/java/jdc/Makefile	Wed Mar 30 23:40:52 2016 +0200
+++ b/java/jdc/Makefile	Sat Apr 09 18:18:34 2016 -0500
@@ -15,7 +15,7 @@
 org_dyncall_DC.h: org/dyncall/DC.class
 	javah -jni org.dyncall.DC
 
-org/dyncall/DC.class:
+org/dyncall/DC.class: org/dyncall/DC.java
 	cd org/dyncall/ && javac DC.java
 
 .PHONY: build clean
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/java/jdc/examples/UnixLibCExample.java	Sat Apr 09 18:18:34 2016 -0500
@@ -0,0 +1,66 @@
+import org.dyncall.DC;
+
+// This example tries to make use of each call in the binding.
+class UnixLibCExample
+{
+   	public static void main(String args[])
+   	{
+		long lib = DC.loadLibrary("/usr/lib/libc.so");
+   		System.out.format("libc.so handle: %x\n", lib);
+
+		long f0 = DC.find(lib, "strlen");
+   		System.out.format("found strlen at: %x\n", f0);
+
+		long f1 = DC.find(lib, "strstr");
+   		System.out.format("found strstr at: %x\n", f1);
+
+		long f2 = DC.find(lib, "strncmp");
+   		System.out.format("found strncmp at: %x\n", f2);
+
+		long vm = DC.newCallVM(4096);
+		DC.reset(vm);
+   		System.out.format("dcGetError() = %d\n", DC.getError(vm));
+		DC.mode(vm, 1234567); // bogus mode, should set error
+   		System.out.format("dcGetError() = %d (after trying to set bogus mode)\n", DC.getError(vm));
+		DC.mode(vm, DC.C_DEFAULT); // good mode, should clear error
+   		System.out.format("dcGetError() = %d (after setting valid mode)\n", DC.getError(vm));
+
+		// String param.
+		DC.argString(vm, "This is a Java string of 33 chars");
+		int r0 = DC.callInt(vm, f0);
+   		System.out.format("strlen(\"This is a Java string of 33 chars\") = %d\n", r0);
+
+		// String param and string/pointer return.
+		DC.reset(vm);
+		DC.argString(vm, "This is a Java string");
+		DC.argString(vm, "Java");
+		String r1 = DC.callString(vm, f1); // will return a copy of the output string, not like a pointer in C
+   		System.out.format("strlen(\"This is a Java string\", \"Java\") = %s\n", r1);
+		long r1l = DC.callPointer(vm, f1); // test returning the pointer as long
+   		System.out.format("strlen(\"This is a Java string\", \"Java\") = 0x%x (returned pointer, pointless here, but serves as example)\n", r1l);
+
+		DC.reset(vm);
+		DC.argString(vm, "This is a Java string");
+		DC.argString(vm, "This is");
+		DC.argInt(vm, 6);
+		int r2 = DC.callInt(vm, f2);
+   		System.out.format("strlen(\"This is a Java string\", \"This is\", 6) = %d\n", r2);
+		DC.reset(vm);
+		DC.argString(vm, "This is a Java string");
+		DC.argString(vm, "This is");
+		DC.argInt(vm, 8);
+		r2 = DC.callInt(vm, f2);
+   		System.out.format("strlen(\"This is a Java string\", \"This is\", 8) = %d\n", r2);
+
+		//DC.reset(vm);
+		//DC.argDouble(vm,  2.);
+		//DC.argDouble(vm, 10.);
+		//double r1 = DC.callDouble(vm, f1);
+   		//System.out.format("pow(2., 10.) = %f\n", r1);
+
+		// Done, cleanup.
+		DC.freeCallVM(vm);
+		DC.freeLibrary(lib);
+	}
+}
+
--- a/java/jdc/examples/UnixMathExample.java	Wed Mar 30 23:40:52 2016 +0200
+++ b/java/jdc/examples/UnixMathExample.java	Sat Apr 09 18:18:34 2016 -0500
@@ -4,11 +4,11 @@
 {
    	public static void main(String args[])
    	{
-		long lib = DC.load("/usr/lib/libm.so");
+		long lib = DC.loadLibrary("/usr/lib/libm.so");
    		System.out.format("libm.so handle: %x\n", lib);
 
 		long f0 = DC.find(lib, "sqrtf");
-   		System.out.format("found sqrft at: %x\n", f0);
+   		System.out.format("found sqrtf at: %x\n", f0);
 
 		long f1 = DC.find(lib, "pow");
    		System.out.format("found pow at: %x\n", f1);
@@ -23,6 +23,10 @@
 		DC.argDouble(vm, 10.);
 		double r1 = DC.callDouble(vm, f1);
    		System.out.format("pow(2., 10.) = %f\n", r1);
+
+		// Done, cleanup.
+		DC.freeCallVM(vm);
+		DC.freeLibrary(lib);
 	}
 }
 
--- a/java/jdc/org/dyncall/DC.java	Wed Mar 30 23:40:52 2016 +0200
+++ b/java/jdc/org/dyncall/DC.java	Sat Apr 09 18:18:34 2016 -0500
@@ -51,9 +51,11 @@
   ;
 
   public static native long newCallVM(int size);
+  public static native void freeCallVM(long vmhandle);
 
-  public static native long   load(String libname);
-  public static native long   find(long libhandle, String symbol);
+  public static native long loadLibrary(String libname);
+  public static native void freeLibrary(long libhandle);
+  public static native long find(long libhandle, String symbol);
   //public static native int    symsCount(long libhandle);
   //public static native String symsName (long libhandle, int index);
 
--- a/java/jdc/org_dyncall_DC.c	Wed Mar 30 23:40:52 2016 +0200
+++ b/java/jdc/org_dyncall_DC.c	Sat Apr 09 18:18:34 2016 -0500
@@ -1,25 +1,51 @@
+#include <stdlib.h>
 #include "org_dyncall_DC.h"
 #include "dyncall.h"
 #include "dynload.h"
 
+// Bookkeping to clean up on reset.
+static int          gc_snum = 0;
+static jobject*     gc_jstr = NULL;
+static const char** gc_cstr = NULL;
+static void cleanupHeldStrings(JNIEnv *pEnv)
+{
+	for(int i=0; i<gc_snum; ++i)
+		(*pEnv)->ReleaseStringUTFChars(pEnv, gc_jstr[i], gc_cstr[i]);
+
+	free(gc_jstr); gc_jstr = NULL;
+	free(gc_cstr); gc_cstr = NULL;
+	gc_snum = 0;
+
+}
+
+
 jlong JNICALL Java_org_dyncall_DC_newCallVM(JNIEnv *pEnv, jclass clazz, jint size)
 {
 	return (jlong)dcNewCallVM(size);
-//@@@ free
 }
 
-jlong JNICALL Java_org_dyncall_DC_load(JNIEnv *pEnv, jclass clazz, jstring s)
+void JNICALL Java_org_dyncall_DC_freeCallVM(JNIEnv *pEnv, jclass clazz, jlong vm)
+{
+	cleanupHeldStrings(pEnv);
+	dcFree((DCCallVM*)vm);
+}
+
+jlong JNICALL Java_org_dyncall_DC_loadLibrary(JNIEnv *pEnv, jclass clazz, jstring s)
 {
 	jlong l = 0;
 	const char *sz = (*pEnv)->GetStringUTFChars(pEnv, s, NULL);
 	if(sz != NULL) {
 		l = (jlong)dlLoadLibrary(sz);
 		(*pEnv)->ReleaseStringUTFChars(pEnv, s, sz);
-//@@@ free
 	}
 	return l;
 }
 
+void JNICALL Java_org_dyncall_DC_freeLibrary(JNIEnv *pEnv, jclass clazz, jlong libhandle)
+{
+	dlFreeLibrary((DLLib*)libhandle);
+}
+
 jlong JNICALL Java_org_dyncall_DC_find(JNIEnv *pEnv, jclass clazz, jlong libhandle, jstring s)
 {
 	jlong l = 0;
@@ -43,13 +69,13 @@
 
 void JNICALL Java_org_dyncall_DC_mode(JNIEnv *pEnv, jclass clazz, jlong vm, jint i)
 {
-	dcMode((DCCallVM*)vm, i);//@@@test
+	dcMode((DCCallVM*)vm, i);
 }
 
 void JNICALL Java_org_dyncall_DC_reset(JNIEnv *pEnv, jclass clazz, jlong vm)
 {
+	cleanupHeldStrings(pEnv);
 	dcReset((DCCallVM*)vm);
-//@@@add cleanup code here for temporary memory held by jni
 }
 
 void JNICALL Java_org_dyncall_DC_argBool(JNIEnv *pEnv, jclass clazz, jlong vm, jboolean b)
@@ -69,7 +95,7 @@
 
 void JNICALL Java_org_dyncall_DC_argInt(JNIEnv *pEnv, jclass clazz, jlong vm, jint i)
 {
-	dcArgInt((DCCallVM*)vm, i);//@@@test
+	dcArgInt((DCCallVM*)vm, i);
 }
 
 void JNICALL Java_org_dyncall_DC_argLong(JNIEnv *pEnv, jclass clazz, jlong vm, jlong l)
@@ -107,8 +133,13 @@
 	const char *sz = (*pEnv)->GetStringUTFChars(pEnv, s, NULL);
 	if(sz != NULL) {
 		dcArgPointer((DCCallVM*)vm, (DCpointer)sz);
-		//(*pEnv)->ReleaseStringUTFChars(pEnv, s, sz);
-		//@@@ free this string when vm is destroyed, reset
+
+		// Bookkeeping, to later release on reset or destruction of vm.
+		gc_jstr = realloc(gc_jstr, (gc_snum+1)*sizeof(jobject));
+		gc_cstr = realloc(gc_cstr, (gc_snum+1)*sizeof(const char*));
+		gc_jstr[gc_snum] = s;
+		gc_cstr[gc_snum] = sz;
+ 		++gc_snum;
 	}
 }
 
@@ -134,7 +165,7 @@
 
 jint JNICALL Java_org_dyncall_DC_callInt(JNIEnv *pEnv, jclass clazz, jlong vm, jlong target)
 {
-	return dcCallInt((DCCallVM*)vm, (DCpointer)target);//@@@test
+	return dcCallInt((DCCallVM*)vm, (DCpointer)target);
 }
 
 jlong JNICALL Java_org_dyncall_DC_callLong(JNIEnv *pEnv, jclass clazz, jlong vm, jlong target)
@@ -159,16 +190,16 @@
 
 jlong JNICALL Java_org_dyncall_DC_callPointer(JNIEnv *pEnv, jclass clazz, jlong vm, jlong target)
 {
-	return (jlong)dcCallPointer((DCCallVM*)vm, (DCpointer)target);//@@@test
+	return (jlong)dcCallPointer((DCCallVM*)vm, (DCpointer)target);
 }
 
 jstring JNICALL Java_org_dyncall_DC_callString(JNIEnv *pEnv, jclass clazz, jlong vm, jlong target)
 {
-	return (*pEnv)->NewStringUTF(pEnv, dcCallPointer((DCCallVM*)vm, (DCpointer)target));//@@@test
+	return (*pEnv)->NewStringUTF(pEnv, dcCallPointer((DCCallVM*)vm, (DCpointer)target));
 }
 
 jint JNICALL Java_org_dyncall_DC_getError(JNIEnv *pEnv, jclass clazz, jlong vm)
 {
-	return dcGetError((DCCallVM*)vm);//@@@test
+	return dcGetError((DCCallVM*)vm);
 }