diff --git a/SWIG/Examples/java/typemap/example.i b/SWIG/Examples/java/typemap/example.i index d50ddc4cc..a29c717d9 100644 --- a/SWIG/Examples/java/typemap/example.i +++ b/SWIG/Examples/java/typemap/example.i @@ -37,51 +37,65 @@ void f1(char *s); * f2 can be seen in Java. */ void f2(char *BYTE); -/* alternative approach uses a StringBuffer typemap for argout */ -/* what is the corresponding jni type */ + +/* 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" - -/* what types to use in java source code */ %typemap(jtype) char *SBUF "StringBuffer" %typemap(jstype) char *SBUF "StringBuffer" -/* how to convert java type to requested c type */ +/* How to convert Java(JNI) type to requested C type */ %typemap(in) char *SBUF { - jclass sbufClass; - jmethodID toStringID; - jmethodID setLengthID; - jstring js; $1 = NULL; if($input != NULL) { - /* get the String from the StringBuffer */ - sbufClass = (*jenv)->GetObjectClass(jenv, $input); - toStringID = (*jenv)->GetMethodID(jenv, sbufClass, "toString", "()Ljava/lang/String;"); - js = (jstring) (*jenv)->CallObjectMethod(jenv, $input, toStringID); - /* convert the String to a char * */ - $1 = (char *)(*jenv)->GetStringUTFChars(jenv, js, 0); - /* zero the original StringBuffer, so we can replace it with the result */ + /* 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 = (jint) (*jenv)->CallObjectMethod(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 type */ +/* How to convert the C type to the Java(JNI) type */ %typemap(argout) char *SBUF { - jclass sbufClass; - jmethodID appendStringID; if($1 != NULL) { - /* append the result to the empty StringBuffer */ - sbufClass = (*jenv)->GetObjectClass(jenv, $input); - appendStringID = (*jenv)->GetMethodID(jenv, sbufClass, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;"); - (*jenv)->CallObjectMethod(jenv, $input, appendStringID, (*jenv)->NewStringUTF(jenv, $1)); - if($input != NULL) (*jenv)->ReleaseStringUTFChars(jenv, $input, $1); + /* 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); +