26 #include "../proxy_cache_interface.hpp" 27 #include "../djinni_common.hpp" 35 #define CJNIEXPORT extern "C" JNIEXPORT 42 void jniInit(JavaVM * jvm);
48 JNIEnv * jniGetThreadEnv();
61 template <
typename Po
interType>
62 class GlobalRef :
public std::unique_ptr<typename std::remove_pointer<PointerType>::type,
70 GlobalRef(JNIEnv * env, PointerType localRef)
72 static_cast<PointerType
>(env->NewGlobalRef(localRef)),
79 template <
typename Po
interType>
80 class LocalRef :
public std::unique_ptr<typename std::remove_pointer<PointerType>::type,
84 LocalRef(JNIEnv * , PointerType localRef)
87 explicit LocalRef(PointerType localRef)
88 : std::unique_ptr<typename std::remove_pointer<PointerType>::type,
LocalRefDeleter>(
93 operator PointerType()
const & {
return this->
get(); }
94 operator PointerType() && =
delete;
98 const T&
get(
const T& x) noexcept {
return x; }
103 const T& release(
const T& x) noexcept {
return x; }
114 std::string m_backtrace;
118 : m_java_exception(env, java_exception) {
119 assert(java_exception);
122 jthrowable java_exception()
const {
return m_java_exception.get(); }
124 const std::string get_backtrace()
const {
return m_backtrace; }
129 void set_as_pending(JNIEnv * env)
const noexcept;
132 void capture_backtrace();
142 void jniConvertAndReleaseJstring(JNIEnv * env, jstring&
string, std::string & out);
151 void jniExceptionCheck(JNIEnv * env);
165 DJINNI_NORETURN_DEFINITION
166 void jniThrowCppFromJavaException(JNIEnv * env, jthrowable java_exception);
171 DJINNI_NORETURN_DEFINITION
172 void jniThrowAssertionError(JNIEnv * env,
const char * file,
int line,
const char * check);
174 #define DJINNI_ASSERT_MSG(check, env, message) \ 176 ::djinni::jniExceptionCheck(env); \ 177 const bool check__res = bool(check); \ 178 ::djinni::jniExceptionCheck(env); \ 180 ::djinni::jniThrowAssertionError(env, __FILE__, __LINE__, message); \ 183 #define DJINNI_ASSERT(check, env) DJINNI_ASSERT_MSG(check, env, #check) 190 using registration_vec = std::vector<std::function<void()>>;
191 static registration_vec get_all();
197 template <
class C>
friend class JniClass;
198 friend void jniInit(JavaVM *);
200 static registration_vec & get_vec();
201 static std::mutex & get_mutex();
225 static const C &
get() {
233 static std::unique_ptr<C> s_singleton;
235 static void allocate() {
238 s_singleton = std::unique_ptr<C>(
new C());
252 jmethodID jniGetStaticMethodID(jclass clazz,
const char * name,
const char * sig);
253 jmethodID jniGetMethodID(jclass clazz,
const char * name,
const char * sig);
254 jfieldID jniGetFieldID(jclass clazz,
const char * name,
const char * sig);
290 using UnowningImplPointer = jobject;
291 using OwningImplPointer = jobject;
292 using OwningProxyPointer = std::shared_ptr<void>;
293 using WeakProxyPointer = std::weak_ptr<void>;
326 using UnowningImplPointer =
void *;
327 using OwningImplPointer = std::shared_ptr<void>;
328 using OwningProxyPointer = jobject;
330 using UnowningImplPointerHash = std::hash<void *>;
331 using UnowningImplPointerEqual = std::equal_to<void *>;
338 static const std::shared_ptr<T> & objectFromHandleAddress(jlong handle) {
340 assert(handle > 4096);
345 const auto & ret = proxy_handle->get();
359 const jmethodID constructor;
360 const jfieldID idField;
367 explicit operator bool()
const {
return bool(clazz); }
378 template <
class I,
class Self>
388 jobject _toJava(JNIEnv* jniEnv,
const std::shared_ptr<I> & c)
const {
395 if (jobject impl = _unwrapJavaProxy<Self>(&c)) {
396 return jniEnv->NewLocalRef(impl);
400 assert(m_cppProxyClass);
401 return JniCppProxyCache::get(
typeid(c), c, &newCppProxy);
412 std::shared_ptr<I> _fromJava(JNIEnv* jniEnv, jobject j)
const {
421 && jniEnv->IsSameObject(jniEnv->GetObjectClass(j), m_cppProxyClass.clazz.get())) {
422 jlong handle = jniEnv->GetLongField(j, m_cppProxyClass.idField);
423 jniExceptionCheck(jniEnv);
424 return objectFromHandleAddress<I>(handle);
429 return _getJavaProxy<Self>(j);
433 JniInterface(
const char * cppProxyClassName) : m_cppProxyClass(cppProxyClassName) {}
436 JniInterface() : m_cppProxyClass{} {}
443 template <
typename S,
typename JavaProxy =
typename S::JavaProxy>
444 jobject _unwrapJavaProxy(
const std::shared_ptr<I> * c)
const {
445 if (
auto proxy = dynamic_cast<JavaProxy *>(c->get())) {
446 return proxy->JavaProxyHandle<JavaProxy>::get().get();
452 template <
typename S>
453 jobject _unwrapJavaProxy(...)
const {
462 static std::pair<jobject, void*> newCppProxy(
const std::shared_ptr<void> & cppObj) {
464 const auto & jniEnv = jniGetThreadEnv();
465 std::unique_ptr<CppProxyHandle<I>> to_encapsulate(
467 jlong handle =
static_cast<jlong
>(
reinterpret_cast<uintptr_t
>(to_encapsulate.get()));
468 jobject cppProxy = jniEnv->NewObject(data.m_cppProxyClass.clazz.get(),
469 data.m_cppProxyClass.constructor,
471 jniExceptionCheck(jniEnv);
472 to_encapsulate.release();
473 return { cppProxy, cppObj.get() };
480 template <
typename S,
typename JavaProxy =
typename S::JavaProxy>
481 std::shared_ptr<I> _getJavaProxy(jobject j)
const {
483 "JavaProxy must derive from JavaProxyCacheEntry");
485 return std::static_pointer_cast<JavaProxy>(JavaProxyCache::get(
486 typeid(JavaProxy), j,
487 [] (
const jobject & obj) -> std::pair<std::shared_ptr<void>, jobject> {
488 auto ret = std::make_shared<JavaProxy>(obj);
489 return { ret, ret->JavaProxyHandle<JavaProxy>::get().get() };
494 template <
typename S>
495 std::shared_ptr<I> _getJavaProxy(...)
const {
531 JniLocalScope(JNIEnv* p_env, jint capacity,
bool throwOnError =
true);
532 bool checkSuccess()
const {
return m_success; }
538 static bool _pushLocalFrame(JNIEnv*
const env, jint capacity);
539 static void _popLocalFrame(JNIEnv*
const env, jobject returnRef);
542 const bool m_success;
545 jstring jniStringFromUTF8(JNIEnv * env,
const std::string & str);
546 std::string jniUTF8FromString(JNIEnv * env,
const jstring jstr);
548 jstring jniStringFromWString(JNIEnv * env,
const std::wstring & str);
549 std::wstring jniWStringFromString(JNIEnv * env,
const jstring jstr);
557 jint ordinal(JNIEnv * env, jobject obj)
const;
565 JniEnum(
const std::string & name);
566 jclass enumClass()
const {
return m_clazz.get(); }
570 const jmethodID m_staticmethValues;
571 const jmethodID m_methOrdinal;
580 unsigned flags(JNIEnv * env, jobject obj)
const;
587 using JniEnum::create;
594 const jmethodID m_methNoneOf { jniGetStaticMethodID(m_clazz.get(),
"noneOf",
"(Ljava/lang/Class;)Ljava/util/EnumSet;") };
595 const jmethodID m_methAdd { jniGetMethodID(m_clazz.get(),
"add",
"(Ljava/lang/Object;)Z") };
596 const jmethodID m_methIterator { jniGetMethodID(m_clazz.get(),
"iterator",
"()Ljava/util/Iterator;") };
597 const jmethodID m_methSize { jniGetMethodID(m_clazz.get(),
"size",
"()I") };
601 const jmethodID methNext { jniGetMethodID(clazz.get(),
"next",
"()Ljava/lang/Object;") };
605 #define DJINNI_FUNCTION_PROLOGUE0(env_) 606 #define DJINNI_FUNCTION_PROLOGUE1(env_, arg1_) 620 void jniSetPendingFromCurrent(JNIEnv * env,
const char * ctx) noexcept;
635 void jniDefaultSetPendingFromCurrent(JNIEnv * env,
const char * ctx) noexcept;
650 #define JNI_TRANSLATE_EXCEPTIONS_RETURN(env, ret) \ 651 catch (const std::exception &) { \ 652 ::djinni::jniSetPendingFromCurrent(env, __func__); \ 669 #define JNI_TRANSLATE_JNI_EXCEPTIONS_RETURN(env, ret) \ 670 catch (const ::djinni::jni_exception & e) { \ 671 e.set_as_pending(env); \ Definition: djinni_support.hpp:59
Definition: djinni_support.hpp:357
Definition: djinni_support.hpp:325
Definition: djinni_support.cpp:217
Definition: djinni_support.hpp:551
Definition: djinni_support.hpp:80
Definition: djinni_support.hpp:188
Definition: djinni_support.hpp:112
Definition: djinni_support.cpp:27
Definition: proxy_cache_interface.hpp:101
Definition: djinni_support.cpp:216
Definition: proxy_cache_interface.hpp:131
Definition: djinni_support.hpp:77
Definition: djinni_support.hpp:522
Definition: djinni_support.hpp:223
Definition: djinni_support.hpp:379
Definition: djinni_support.hpp:574
Definition: djinni_support.cpp:679
Definition: djinni_support.hpp:289
Definition: djinni_support.hpp:62