diff options
Diffstat (limited to 'Lib/java')
-rw-r--r-- | Lib/java/director.swg | 19 | ||||
-rw-r--r-- | Lib/java/java.swg | 5 | ||||
-rw-r--r-- | Lib/java/std_string.i | 6 | ||||
-rw-r--r-- | Lib/java/various.i | 38 |
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 "" + |