#pragma once #include #include namespace jni { struct WeakReferenceTag { static constexpr auto Name() { return "java/lang/ref/WeakReference"; } }; // Wraps a JNI global reference to a java.lang.ref.WeakReference, producing an ownership class // similar to jni::Weak (JNI's weak global reference), but with more reliable promotion semantics. // Whereas a JNI weak global reference may still be promoted to a strong reference even during // finalization, leading to potential use-after-free errors, a WeakReference cannot. template < class T, template < RefDeletionMethod > class Deleter = DefaultRefDeleter > class WeakReference { private: Global, Deleter> reference; public: WeakReference(JNIEnv& env, const T& referent) { static auto& klass = Class::Singleton(env); static auto constructor = klass.GetConstructor>(env); reference = NewGlobal(env, klass.New(env, constructor, referent)); } Local get(JNIEnv& env) { if (!reference) { return Local(); } static auto& klass = Class::Singleton(env); static auto get = klass.template GetMethod ()>(env, "get"); return Local(env, reinterpret_cast(reference.Call(env, get).release())); } }; }