summaryrefslogtreecommitdiff
path: root/Lib/java
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/java')
-rw-r--r--Lib/java/director.swg19
-rw-r--r--Lib/java/java.swg5
-rw-r--r--Lib/java/std_string.i6
-rw-r--r--Lib/java/various.i38
4 files changed, 63 insertions, 5 deletions
diff --git a/Lib/java/director.swg b/Lib/java/director.swg
index 819ad903d..031cdf2a9 100644
--- a/Lib/java/director.swg
+++ b/Lib/java/director.swg
@@ -100,6 +100,22 @@ namespace Swig {
bool weak_global_;
};
+ /* Local JNI reference deleter */
+ class LocalRefGuard {
+ JNIEnv *jenv_;
+ jobject jobj_;
+
+ // non-copyable
+ LocalRefGuard(const LocalRefGuard &);
+ LocalRefGuard &operator=(const LocalRefGuard &);
+ public:
+ LocalRefGuard(JNIEnv *jenv, jobject jobj): jenv_(jenv), jobj_(jobj) {}
+ ~LocalRefGuard() {
+ if (jobj_)
+ jenv_->DeleteLocalRef(jobj_);
+ }
+ };
+
/* director base class */
class Director {
/* pointer to Java virtual machine */
@@ -152,6 +168,7 @@ namespace Swig {
JNIEnvWrapper jnienv(this) ;
JNIEnv *jenv = jnienv.getJNIEnv() ;
jobject jobj = swig_self_.get(jenv);
+ LocalRefGuard ref_deleter(jenv, jobj);
#if defined(DEBUG_DIRECTOR_OWNED)
std::cout << "Swig::Director::disconnect_director_self(" << jobj << ")" << std::endl;
#endif
@@ -164,7 +181,6 @@ namespace Swig {
jenv->CallVoidMethod(jobj, disconn_meth);
}
}
- jenv->DeleteLocalRef(jobj);
}
public:
@@ -379,6 +395,5 @@ namespace Swig {
}
return matches;
}
-
}
diff --git a/Lib/java/java.swg b/Lib/java/java.swg
index 3d4d83730..98524e85e 100644
--- a/Lib/java/java.swg
+++ b/Lib/java/java.swg
@@ -400,11 +400,13 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
}
%typemap(directorin, descriptor="Ljava/lang/String;", noblock=1) char * {
- $input = 0;
+ $input = 0;
if ($1) {
$input = JCALL1(NewStringUTF, jenv, (const char *)$1);
if (!$input) return $null;
}
+ Swig::LocalRefGuard $1_refguard(jenv, $input);
+// boohoo
}
%typemap(freearg, noblock=1) char * { if ($1) JCALL2(ReleaseStringUTFChars, jenv, $input, (const char *)$1); }
@@ -731,6 +733,7 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
$input = JCALL1(NewStringUTF, jenv, (const char *)$1);
if (!$input) return $null;
}
+ Swig::LocalRefGuard $1_refguard(jenv, $input);
}
%typemap(argout) char[ANY], char[] ""
diff --git a/Lib/java/std_string.i b/Lib/java/std_string.i
index 5ad7d30bc..830a89611 100644
--- a/Lib/java/std_string.i
+++ b/Lib/java/std_string.i
@@ -49,7 +49,8 @@ class string;
jenv->ReleaseStringUTFChars($input, $1_pstr); %}
%typemap(directorin,descriptor="Ljava/lang/String;") string
-%{ $input = jenv->NewStringUTF($1.c_str()); %}
+%{ $input = jenv->NewStringUTF($1.c_str());
+ Swig::LocalRefGuard $1_refguard(jenv, $input); %}
%typemap(out) string
%{ $result = jenv->NewStringUTF($1.c_str()); %}
@@ -98,7 +99,8 @@ class string;
jenv->ReleaseStringUTFChars($input, $1_pstr); %}
%typemap(directorin,descriptor="Ljava/lang/String;") const string &
-%{ $input = jenv->NewStringUTF($1.c_str()); %}
+%{ $input = jenv->NewStringUTF($1.c_str());
+ Swig::LocalRefGuard $1_refguard(jenv, $input); %}
%typemap(out) const string &
%{ $result = jenv->NewStringUTF($1->c_str()); %}
diff --git a/Lib/java/various.i b/Lib/java/various.i
index 7ba7a5eb3..bfcf346d3 100644
--- a/Lib/java/various.i
+++ b/Lib/java/various.i
@@ -92,6 +92,7 @@
* The returned string appears in the 1st element of the passed in Java String array.
*
* Example usage wrapping:
+ * %apply char **STRING_OUT { char **string_out };
* void foo(char **string_out);
*
* Java usage:
@@ -154,3 +155,40 @@
/* Prevent default freearg typemap from being used */
%typemap(freearg) char *BYTE ""
+/*
+ * unsigned char *NIOBUFFER typemaps.
+ * This is for mapping Java nio buffers to C char arrays.
+ * It is useful for performance critical code as it reduces the memory copy an marshaling overhead.
+ * Note: The Java buffer has to be allocated with allocateDirect.
+ *
+ * Example usage wrapping:
+ * %apply unsigned char *NIOBUFFER { unsigned char *buf };
+ * void foo(unsigned char *buf);
+ *
+ * Java usage:
+ * java.nio.ByteBuffer b = ByteBuffer.allocateDirect(20);
+ * modulename.foo(b);
+ */
+%typemap(jni) unsigned char *NIOBUFFER "jobject"
+%typemap(jtype) unsigned char *NIOBUFFER "java.nio.ByteBuffer"
+%typemap(jstype) unsigned char *NIOBUFFER "java.nio.ByteBuffer"
+%typemap(javain,
+ pre=" assert $javainput.isDirect() : \"Buffer must be allocated direct.\";") unsigned char *NIOBUFFER "$javainput"
+%typemap(javaout) unsigned char *NIOBUFFER {
+ return $jnicall;
+}
+%typemap(in) unsigned char *NIOBUFFER {
+ $1 = (unsigned char *) JCALL1(GetDirectBufferAddress, jenv, $input);
+ if ($1 == NULL) {
+ SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, "Unable to get address of a java.nio.ByteBuffer direct byte buffer. Buffer must be a direct buffer and not a non-direct buffer.");
+ }
+}
+%typemap(memberin) unsigned char *NIOBUFFER {
+ if ($input) {
+ $1 = $input;
+ } else {
+ $1 = 0;
+ }
+}
+%typemap(freearg) unsigned char *NIOBUFFER ""
+