32
32
#include " implementation/jni_helper/lifecycle_string.h"
33
33
#include " implementation/jvm.h"
34
34
#include " implementation/proxy.h"
35
+ #include " implementation/proxy_temporary.h"
35
36
#include " implementation/proxy_convenience_aliases.h"
36
37
#include " implementation/ref_base.h"
37
38
#include " jni_dep.h"
38
39
39
40
namespace jni {
40
-
41
41
template <typename JString>
42
42
struct Proxy <JString,
43
43
typename std::enable_if_t <std::is_same_v<JString, jstring>>>
@@ -68,22 +68,36 @@ struct Proxy<JString,
68
68
IsConvertibleKey<T>::template value<std::string_view> ||
69
69
std::is_same_v<T, LocalString> || std::is_same_v<T, GlobalString>;
70
70
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
+
71
81
// These leak local instances of strings. Usually, RAII mechanisms would
72
82
// correctly release local instances, but here we are stripping that so it can
73
83
// be used in a method. This could be obviated by wrapping the calling scope
74
84
// in a local stack frame.
75
- static jstring ProxyAsArg (jstring s) { return s; }
85
+ static jstring ProxyAsArg (jstring s) {
86
+ return s;
87
+ }
76
88
89
+ // Note: Because a temporary is created `ProxyTemporary` is used to
90
+ // guarantee the release of the underlying local after use in `ProxyAsArg`.
77
91
template <typename T,
78
92
typename = std::enable_if_t <std::is_same_v<T, const char *> ||
79
93
std::is_same_v<T, std::string> ||
80
94
std::is_same_v<T, std::string_view>>>
81
- static jstring ProxyAsArg (T s) {
95
+ static ProxyTemporary< jstring, DeleteLocalRef> ProxyAsArg (T s) {
82
96
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)} ;
84
98
} else {
85
- return LifecycleHelper<jstring, LifecycleType::LOCAL>::Construct (
86
- s.data ());
99
+ return { LifecycleHelper<jstring, LifecycleType::LOCAL>::Construct (
100
+ s.data ())} ;
87
101
}
88
102
}
89
103
@@ -101,7 +115,6 @@ struct Proxy<JString,
101
115
return t.Release ();
102
116
}
103
117
};
118
+ } // namespace jni
104
119
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