diff options
Diffstat (limited to 'Examples/java/typemap')
-rw-r--r-- | Examples/java/typemap/Makefile | 18 | ||||
-rw-r--r-- | Examples/java/typemap/example.i | 101 | ||||
-rw-r--r-- | Examples/java/typemap/index.html | 32 | ||||
-rw-r--r-- | Examples/java/typemap/runme.java | 26 |
4 files changed, 177 insertions, 0 deletions
diff --git a/Examples/java/typemap/Makefile b/Examples/java/typemap/Makefile new file mode 100644 index 0000000..92afbd4 --- /dev/null +++ b/Examples/java/typemap/Makefile @@ -0,0 +1,18 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +SRCS = +TARGET = example +INTERFACE = example.i +SWIGOPT = + +all:: java + +java:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' java + javac *.java + +clean:: + $(MAKE) -f $(TOP)/Makefile java_clean + +check: all diff --git a/Examples/java/typemap/example.i b/Examples/java/typemap/example.i new file mode 100644 index 0000000..7c97e66 --- /dev/null +++ b/Examples/java/typemap/example.i @@ -0,0 +1,101 @@ +/* File : example.i */ +%module example +%{ +/* + example of a function that returns a value in the char * argument + normally used like: + + char buf[bigenough]; + f1(buf); +*/ + +void f1(char *s) { + if(s != NULL) { + sprintf(s, "hello world"); + } +} + +void f2(char *s) { + f1(s); +} + +void f3(char *s) { + f1(s); +} + +%} + +/* default behaviour is that of input arg, Java cannot return a value in a + * string argument, so any changes made by f1(char*) will not be seen in the Java + * string passed to the f1 function. +*/ +void f1(char *s); + +%include various.i + +/* use the BYTE argout typemap to get around this. Changes in the string by + * f2 can be seen in Java. */ +void f2(char *BYTE); + + + +/* Alternative approach uses a StringBuffer typemap for argout */ + +/* Define the types to use in the generated JNI C code and Java code */ +%typemap(jni) char *SBUF "jobject" +%typemap(jtype) char *SBUF "StringBuffer" +%typemap(jstype) char *SBUF "StringBuffer" + +/* How to convert Java(JNI) type to requested C type */ +%typemap(in) char *SBUF { + + $1 = NULL; + if($input != NULL) { + /* Get the String from the StringBuffer */ + jmethodID setLengthID; + jclass sbufClass = (*jenv)->GetObjectClass(jenv, $input); + jmethodID toStringID = (*jenv)->GetMethodID(jenv, sbufClass, "toString", "()Ljava/lang/String;"); + jstring js = (jstring) (*jenv)->CallObjectMethod(jenv, $input, toStringID); + + /* Convert the String to a C string */ + const char *pCharStr = (*jenv)->GetStringUTFChars(jenv, js, 0); + + /* Take a copy of the C string as the typemap is for a non const C string */ + jmethodID capacityID = (*jenv)->GetMethodID(jenv, sbufClass, "capacity", "()I"); + jint capacity = (*jenv)->CallIntMethod(jenv, $input, capacityID); + $1 = (char *) malloc(capacity+1); + strcpy($1, pCharStr); + + /* Release the UTF string we obtained with GetStringUTFChars */ + (*jenv)->ReleaseStringUTFChars(jenv, js, pCharStr); + + /* Zero the original StringBuffer, so we can replace it with the result */ + setLengthID = (*jenv)->GetMethodID(jenv, sbufClass, "setLength", "(I)V"); + (*jenv)->CallVoidMethod(jenv, $input, setLengthID, (jint) 0); + } +} + +/* How to convert the C type to the Java(JNI) type */ +%typemap(argout) char *SBUF { + + if($1 != NULL) { + /* Append the result to the empty StringBuffer */ + jstring newString = (*jenv)->NewStringUTF(jenv, $1); + jclass sbufClass = (*jenv)->GetObjectClass(jenv, $input); + jmethodID appendStringID = (*jenv)->GetMethodID(jenv, sbufClass, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;"); + (*jenv)->CallObjectMethod(jenv, $input, appendStringID, newString); + + /* Clean up the string object, no longer needed */ + free($1); + $1 = NULL; + } +} +/* Prevent the default freearg typemap from being used */ +%typemap(freearg) char *SBUF "" + +/* Convert the jstype to jtype typemap type */ +%typemap(javain) char *SBUF "$javainput" + +/* apply the new typemap to our function */ +void f3(char *SBUF); + diff --git a/Examples/java/typemap/index.html b/Examples/java/typemap/index.html new file mode 100644 index 0000000..5dd5919 --- /dev/null +++ b/Examples/java/typemap/index.html @@ -0,0 +1,32 @@ +<html> +<head> +<title>SWIG:Examples:java:typemap</title> +</head> + +<body bgcolor="#ffffff"> + + +<tt>SWIG/Examples/java/typemap/</tt> +<hr> + +<H2>Typemaps in Java</H2> + +<p> +This example shows how typemaps can be used to modify the default behaviour of the Java SWIG module. + +<ul> +<li><a href="example.i">example.i</a>. Interface file. +<li><a href="runme.java">runme.java</a>. Sample Java program. +</ul> + +<h2>Notes</h2> + +<ul> +<li>Shows how to pass strings to Java from c and visa versa. +<li>Typemaps can modify the default behaviour of the Java SWIG module. +<li>The default c to java mapping can be modified using typemaps. +</ul> + +<hr> +</body> +</html> diff --git a/Examples/java/typemap/runme.java b/Examples/java/typemap/runme.java new file mode 100644 index 0000000..fcbcc30 --- /dev/null +++ b/Examples/java/typemap/runme.java @@ -0,0 +1,26 @@ + +public class runme { + + static { + try { + System.loadLibrary("example"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e); + System.exit(1); + } + } + + public static void main(String argv[]) { + String s = "brave new world"; + example.f1(s); + System.out.println("f1(String): " + s); + + byte b[] = new byte[25]; + example.f2(b); + System.out.println("f2(byte[]): " + new String(b)); + + StringBuffer sb = new StringBuffer(20); + example.f3(sb); + System.out.println("f3(StringBuffer): " + sb); + } +} |