On 04.06.2015 18:49, Branko Čibej wrote:
> On 04.06.2015 18:42, Atri Sharma wrote:
>> I like proxy objects although I am wondering if that makes copy by value
>> any more expensive (I am not sure about deep copying of non native objects)
> Note that the only data a proxy object contains is the Java reference --
> a pointer by the current JNI definition. What makes copying more
> expensive is the requirement to maintain a Java global reference in each
> copy. For this, you can either use JNI's NewGlobalRef/DeleteGlobalRef,
> or some kind of native reference counting in C++ -- effectively a shared
> pointer to a (wrapped) Java global reference. I have no ides what's
> faster, but I suspect that the letting JNI take care of reference
> handling is the better option.
Something like the attached prototype.
-- Brane
#include <jni.h>
#include <memory>
#include <stdexcept>
class JavaProxyMixin
{
protected:
JavaProxyMixin(const JavaProxyMixin& other)
: m_env(other.m_env),
m_jthis(makeref(other.m_env, other.m_jthis))
{}
~JavaProxyMixin()
{
if (m_jthis)
m_env->DeleteGlobalRef(m_jthis);
}
JavaProxyMixin& operator=(const JavaProxyMixin& other)
{
this->~JavaProxyMixin();
return *new(this) JavaProxyMixin(other);
}
explicit JavaProxyMixin(JNIEnv* env, jobject jthis)
: m_env(env),
m_jthis(makeref(env, jthis))
{}
private:
jobject makeref(JNIEnv* env, jobject jthis)
{
if (!jthis)
throw std::invalid_argument("null reference");
jobject jref = env->NewGlobalRef(jthis);
if (!jref)
throw std::bad_alloc();
return jref;
}
protected:
JNIEnv* const m_env;
jobject const m_jthis;
};
// Example usage
class ObjectWrapper : private JavaProxyMixin
{
public:
explicit ObjectWrapper(JNIEnv* env, jobject jthis)
: JavaProxyMixin(env, jthis)
{}
void fooblerize()
{
// Note: needs more error handling
jclass cls = m_env->FindClass("JavaClass");
jmethodID mid = m_env->GetMethodID(cls, "fooblerize", "()V");
m_env->CallVoidMethod(m_jthis, mid);
}
};