3232#include " implementation/jni_helper/lifecycle_string.h"
3333#include " implementation/jvm.h"
3434#include " implementation/proxy.h"
35+ #include " implementation/proxy_temporary.h"
3536#include " implementation/proxy_convenience_aliases.h"
3637#include " implementation/ref_base.h"
3738#include " jni_dep.h"
3839
3940namespace jni {
40-
4141template <typename JString>
4242struct Proxy <JString,
4343 typename std::enable_if_t <std::is_same_v<JString, jstring>>>
@@ -68,22 +68,36 @@ struct Proxy<JString,
6868 IsConvertibleKey<T>::template value<std::string_view> ||
6969 std::is_same_v<T, LocalString> || std::is_same_v<T, GlobalString>;
7070
71+ static constexpr auto DeleteLambda = [](const jstring& s) {
72+ JniEnv::GetEnv ()->DeleteLocalRef (static_cast <jobject>(s));
73+ };
74+
75+ struct DeleteLocalRef {
76+ static void Call (const jstring& s) {
77+ JniEnv::GetEnv ()->DeleteLocalRef (static_cast <jobject>(s));
78+ }
79+ };
80+
7181 // These leak local instances of strings. Usually, RAII mechanisms would
7282 // correctly release local instances, but here we are stripping that so it can
7383 // be used in a method. This could be obviated by wrapping the calling scope
7484 // in a local stack frame.
75- static jstring ProxyAsArg (jstring s) { return s; }
85+ static jstring ProxyAsArg (jstring s) {
86+ return s;
87+ }
7688
89+ // Note: Because a temporary is created `ProxyTemporary` is used to
90+ // guarantee the release of the underlying local after use in `ProxyAsArg`.
7791 template <typename T,
7892 typename = std::enable_if_t <std::is_same_v<T, const char *> ||
7993 std::is_same_v<T, std::string> ||
8094 std::is_same_v<T, std::string_view>>>
81- static jstring ProxyAsArg (T s) {
95+ static ProxyTemporary< jstring, DeleteLocalRef> ProxyAsArg (T s) {
8296 if constexpr (std::is_same_v<T, const char *>) {
83- return LifecycleHelper<jstring, LifecycleType::LOCAL>::Construct (s);
97+ return { LifecycleHelper<jstring, LifecycleType::LOCAL>::Construct (s)} ;
8498 } else {
85- return LifecycleHelper<jstring, LifecycleType::LOCAL>::Construct (
86- s.data ());
99+ return { LifecycleHelper<jstring, LifecycleType::LOCAL>::Construct (
100+ s.data ())} ;
87101 }
88102 }
89103
@@ -101,7 +115,6 @@ struct Proxy<JString,
101115 return t.Release ();
102116 }
103117};
118+ } // namespace jni
104119
105- } // namespace jni
106-
107- #endif // JNI_BIND_IMPLEMENTATION_PROXY_DEFINITIONS_STRING_H_
120+ #endif // JNI_BIND_IMPLEMENTATION_PROXY_DEFINITIONS_STRING_H_
0 commit comments