summaryrefslogtreecommitdiff
path: root/Examples/java/typemap
diff options
context:
space:
mode:
Diffstat (limited to 'Examples/java/typemap')
-rw-r--r--Examples/java/typemap/Makefile18
-rw-r--r--Examples/java/typemap/example.i101
-rw-r--r--Examples/java/typemap/index.html32
-rw-r--r--Examples/java/typemap/runme.java26
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);
+ }
+}