summaryrefslogtreecommitdiffstats
path: root/java/jni
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2020-05-04 15:33:27 +0200
committerSven Gothel <[email protected]>2020-05-04 15:33:27 +0200
commit1dc2a63afd3c56551495cc43656cebb6ba72098f (patch)
tree2c23a6dcc480315ae05fe73e17b1a4c86225fec4 /java/jni
parentd3bfa855b3eadea10cd0e45bfb5bb5c982971f5f (diff)
JNIGlobalRef: Add copy-ctor, move-ctor and equality operations
Goal is to utilize JNIGlobalRef as a first class shared jobject instance without the need to use std::shared_ptr<JNIGlobalRef>. +++ Efficiency and functionality: Add copy-ctor, move-ctor - Allow a JNIGlobalRef to be shared by creating copies with a 'NewGlobalRef(..)'. - Allow JNIGlobalRef to be moved by 'nulling' the source jobject +++ Functionality: Add equality operations - test inner jobject via 'IsSameObject(..)'
Diffstat (limited to 'java/jni')
-rw-r--r--java/jni/JNIMem.cxx60
-rw-r--r--java/jni/JNIMem.hpp11
2 files changed, 68 insertions, 3 deletions
diff --git a/java/jni/JNIMem.cxx b/java/jni/JNIMem.cxx
index ecea39aa..992b1a95 100644
--- a/java/jni/JNIMem.cxx
+++ b/java/jni/JNIMem.cxx
@@ -26,8 +26,17 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
+#include <cstdio>
+
#include "JNIMem.hpp"
+// #define VERBOSE_ON 1
+#ifdef VERBOSE_ON
+ #define DBG_PRINT(...) { fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n"); fflush(stderr); }
+#else
+ #define DBG_PRINT(...)
+#endif
+
JavaVM* vm;
thread_local JNIEnvContainer jni_env;
@@ -92,6 +101,41 @@ JNIGlobalRef::JNIGlobalRef(jobject object) {
throw direct_bt::RuntimeException("JNIGlobalRef ctor null jobject", E_FILE_LINE);
}
this->object = jni_env->NewGlobalRef(object);
+ DBG_PRINT("JNIGlobalRef::def_ctor %p -> %p", object, this->object);
+}
+
+JNIGlobalRef::JNIGlobalRef(const JNIGlobalRef &o) {
+ if( nullptr == o.object ) {
+ throw direct_bt::RuntimeException("Other JNIGlobalRef jobject is null", E_FILE_LINE);
+ }
+ object = jni_env->NewGlobalRef(o.object);
+ DBG_PRINT("JNIGlobalRef::copy_ctor %p -> %p", o.object, object);
+}
+JNIGlobalRef::JNIGlobalRef(JNIGlobalRef &&o)
+: object(o.object) {
+ DBG_PRINT("JNIGlobalRef::move_ctor %p (nulled) -> %p", o.object, object);
+ o.object = nullptr;
+}
+JNIGlobalRef& JNIGlobalRef::operator=(const JNIGlobalRef &o) {
+ if( &o == this ) {
+ return *this;
+ }
+ JNIEnv * env = *jni_env;
+ if( nullptr != object ) { // always
+ env->DeleteGlobalRef(object);
+ }
+ if( nullptr == o.object ) {
+ throw direct_bt::RuntimeException("Other JNIGlobalRef jobject is null", E_FILE_LINE);
+ }
+ object = jni_env->NewGlobalRef(o.object);
+ DBG_PRINT("JNIGlobalRef::copy_assign %p -> %p", o.object, object);
+ return *this;
+}
+JNIGlobalRef& JNIGlobalRef::operator=(JNIGlobalRef &&o) {
+ object = o.object;
+ DBG_PRINT("JNIGlobalRef::move_assign %p (nulled) -> %p", o.object, object);
+ o.object = nullptr;
+ return *this;
}
JNIGlobalRef::~JNIGlobalRef() {
@@ -100,12 +144,22 @@ JNIGlobalRef::~JNIGlobalRef() {
if( nullptr == env ) {
throw direct_bt::RuntimeException("JNIGlobalRef dtor null JNIEnv", E_FILE_LINE);
}
- if( nullptr == object ) {
- throw direct_bt::RuntimeException("JNIGlobalRef dtor null jobject", E_FILE_LINE);
- } else {
+ DBG_PRINT("JNIGlobalRef::dtor %p", object);
+ if( nullptr != object ) {
+ // due to move ctor and assignment, we accept nullptr object
env->DeleteGlobalRef(object);
}
} catch (std::exception &e) {
fprintf(stderr, "JNIGlobalRef dtor: Caught %s\n", e.what());
}
}
+
+bool JNIGlobalRef::operator==(const JNIGlobalRef& rhs) const {
+ if( &rhs == this ) {
+ DBG_PRINT("JNIGlobalRef::== true: %p == %p (ptr)", object, rhs.object);
+ return true;
+ }
+ bool res = JNI_TRUE == jni_env->IsSameObject(object, rhs.object);
+ DBG_PRINT("JNIGlobalRef::== %d: %p == %p (IsSameObject)", res, object, rhs.object);
+ return res;
+}
diff --git a/java/jni/JNIMem.hpp b/java/jni/JNIMem.hpp
index a133bd9a..b7f5323b 100644
--- a/java/jni/JNIMem.hpp
+++ b/java/jni/JNIMem.hpp
@@ -84,6 +84,12 @@ public:
/* Creates a GlobalRef from an object passed to it */
JNIGlobalRef(jobject object);
+ JNIGlobalRef(const JNIGlobalRef &o);
+ JNIGlobalRef(JNIGlobalRef &&o);
+
+ JNIGlobalRef& operator=(const JNIGlobalRef &o);
+ JNIGlobalRef& operator=(JNIGlobalRef &&o);
+
/* Deletes the stored GlobalRef */
~JNIGlobalRef();
@@ -94,6 +100,11 @@ public:
jobject getObject() const { return object; }
/* Provides access to the stored GlobalRef as a jclass. */
jclass getClass() const { return (jclass)object; }
+
+ bool operator==(const JNIGlobalRef& rhs) const;
+
+ bool operator!=(const JNIGlobalRef& rhs) const
+ { return !( *this == rhs ); }
};
#endif /* JNIMEM__HPP_ */