diff --git a/examples/AndroidMath/AndroidMath.java b/examples/AndroidMath/AndroidMath.java index fef2b0526..b268052e7 100644 --- a/examples/AndroidMath/AndroidMath.java +++ b/examples/AndroidMath/AndroidMath.java @@ -7,9 +7,4 @@ public class AndroidMath // Native stuff - C/C++ public static native int power(int number, int n); - static { - // In this place we are loading native libraries. - // Native library always has upp package name! - System.loadLibrary("AndroidMath"); - } } diff --git a/examples/AndroidMath/AndroidMath.upp b/examples/AndroidMath/AndroidMath.upp index 4df70360b..8ff1ed6da 100644 --- a/examples/AndroidMath/AndroidMath.upp +++ b/examples/AndroidMath/AndroidMath.upp @@ -3,6 +3,9 @@ description "Android builder juicy example\377"; uses AndroidMathUtility; +library + log; + file MemoryManager readonly separator, MemoryManager.h, diff --git a/examples/AndroidMath/AndroidMathActivity.java b/examples/AndroidMath/AndroidMathActivity.java index 894b07e7f..657263008 100644 --- a/examples/AndroidMath/AndroidMathActivity.java +++ b/examples/AndroidMath/AndroidMathActivity.java @@ -59,4 +59,15 @@ public class AndroidMathActivity extends Activity tv.append(text); } + + static { + // For Android version less than 5.0 we need to specific standard library + // System.loadLibrary("gnustl_shared"); + System.loadLibrary("c++_shared"); + + // In this place we are loading native libraries (In revers dependency order). + // IMPORTANT: Native library always has upp package name!!! + System.loadLibrary("AndroidMathUtility"); + System.loadLibrary("AndroidMath"); + } } diff --git a/examples/AndroidMath/MemoryManager.h b/examples/AndroidMath/MemoryManager.h index fd3994f2f..5d0dc238f 100644 --- a/examples/AndroidMath/MemoryManager.h +++ b/examples/AndroidMath/MemoryManager.h @@ -1,8 +1,16 @@ #ifndef _JniMath_MemoryManager_h_ #define _JniMath_MemoryManager_h_ +#include + #include #include +#include +#include + +#define FIELD_NATIVE_ADRESS "nativeAdress" + +#define LONG_SIG "J" /** * Java simple memory manager. @@ -10,36 +18,41 @@ template class MemoryManager { public: - void Insert(JNIEnv *env, jobject jobj, const T& obj) + ~MemoryManager() { - jobject weakGlobalRef = env->NewWeakGlobalRef(jobj); - if(!env->IsSameObject(weakGlobalRef, NULL)) { - objs.push_back(env->NewWeakGlobalRef(weakGlobalRef)); - values.push_back(obj); + for(int i = 0; i < values.size(); i++) { + delete values[i]; + } + } + + void Insert(JNIEnv *env, jobject jobj, T* value) + { + if(jobj != NULL) { + values.push_back(value); + + SetNativeAdress(env, jobj, values[values.size() - 1]); } } - void MakeCopy(JNIEnv *env, jobject jobjSrc, jobject jobjDst) + void MakeCopy(JNIEnv *env, jobject jobjThis, jobject jobjThat) { - if(!env->IsSameObject(jobjSrc, jobjDst)) { - T t(*Get(env, jobjSrc)); - Insert(env, jobjSrc, t); + if(!env->IsSameObject(jobjThis, jobjThat)) { + T* t = Get(env, jobjThat); + Insert(env, jobjThis, t); } } void Erase(JNIEnv *env, jobject jobj) { int idx = FindIdx(env, jobj); - if(idx >= 0) { - objs.erase(objs.begin() + idx); + if(idx >= 0) values.erase(values.begin() + idx); - } } T* Get(JNIEnv *env, jobject jobj) { int idx = FindIdx(env, jobj); - return idx >= 0 ? &values[idx] : NULL; + return idx >= 0 ? values[idx] : NULL; } int GetCount() @@ -50,17 +63,38 @@ public: private: int FindIdx(JNIEnv *env, jobject jobj) { - for(int i = 0; i < objs.size(); i++) { - if(env->IsSameObject(objs[i], jobj)) { + for(int i = 0; i < values.size(); i++) { + if(GetNativeAdress(env, jobj) == values[i]) { return i; } } - return 0; + return -1; } - + private: - std::vector objs; - std::vector values; + T* GetNativeAdress(JNIEnv* env, jobject jobj) + { + jclass objectClass = env->GetObjectClass(jobj); + + jfieldID adressField = GetNativeAdressField(env, objectClass); + return (T*)env->GetLongField(jobj, adressField); + } + + void SetNativeAdress(JNIEnv* env, jobject jobj, T* obj) + { + jclass objectClass = env->GetObjectClass(jobj); + + jfieldID adressField = GetNativeAdressField(env, objectClass); + env->SetLongField(jobj, adressField, (jlong)obj); + } + + jfieldID GetNativeAdressField(JNIEnv* env, jclass clazz) + { + return env->GetFieldID(clazz, FIELD_NATIVE_ADRESS, LONG_SIG); + } + +private: + std::vector values; }; #endif diff --git a/examples/AndroidMath/Vector.cpp b/examples/AndroidMath/Vector.cpp index e08887d54..0c5b3da23 100644 --- a/examples/AndroidMath/Vector.cpp +++ b/examples/AndroidMath/Vector.cpp @@ -17,7 +17,7 @@ extern "C" { using AndroidMathUtility::Vector; -MemoryManager mm; +static MemoryManager mm; /* * Class: org_upp_AndroidMath_Vector @@ -27,7 +27,7 @@ MemoryManager mm; JNIEXPORT void JNICALL Java_org_upp_AndroidMath_Vector_construct (JNIEnv *env, jobject obj, jint size) { - mm.Insert(env, obj, Vector(size)); + mm.Insert(env, obj, new Vector(size)); } /* @@ -36,9 +36,9 @@ JNIEXPORT void JNICALL Java_org_upp_AndroidMath_Vector_construct * Signature: (Lorg/upp/AndroidMath/Vector;)V */ JNIEXPORT void JNICALL Java_org_upp_AndroidMath_Vector_copyConstruct - (JNIEnv *env, jobject objSrc, jobject objDst) + (JNIEnv *env, jobject jobjThis, jobject jobjThat) { - mm.MakeCopy(env, objSrc, objDst); + mm.MakeCopy(env, jobjThis, jobjThat); } /* @@ -46,7 +46,7 @@ JNIEXPORT void JNICALL Java_org_upp_AndroidMath_Vector_copyConstruct * Method: destruct * Signature: ()V */ -JNIEXPORT void JNICALL Java_org_upp_AndroidMath_Vector_destroy +JNIEXPORT void JNICALL Java_org_upp_AndroidMath_Vector_nativeFinalize (JNIEnv *env, jobject obj) { mm.Erase(env, obj); diff --git a/examples/AndroidMath/Vector.java b/examples/AndroidMath/Vector.java index 764a4d7d9..ae31d007e 100644 --- a/examples/AndroidMath/Vector.java +++ b/examples/AndroidMath/Vector.java @@ -5,6 +5,23 @@ package org.upp.AndroidMath; */ public class Vector { + /** + * Field use by MemoryManager to stroe pointer to c++ object. + * If you want to use MemoryManager with your class make usre you have this field + * in your class. + */ + private long nativeAdress = 0; + + /** + * We override finalize method, beacuse we need to destroy native c++ object. + */ + @Override + protected void finalize() throws Throwable + { + nativeFinalize(); + super.finalize(); + } + public Vector(int size) { construct(size); @@ -15,16 +32,6 @@ public class Vector copyConstruct(vec); } - /** - * We override finalize method due to possibilite of memory leaks. - */ - @Override - protected void finalize() throws Throwable - { - destroy(); - super.finalize(); - } - // Native stuff - C/C++ public native int getSize(); public native float get(int id); @@ -37,11 +44,5 @@ public class Vector private native void construct(int size); private native void copyConstruct(Vector vec); - private native void destroy(); - - static { - // In this place we are loading native libraries. - // Native library always has upp package name! - System.loadLibrary("AndroidMath"); - } + private native void nativeFinalize(); } diff --git a/examples/AndroidMathUtility/Vector.cpp b/examples/AndroidMathUtility/Vector.cpp index 2b5d8e98c..5a078386e 100644 --- a/examples/AndroidMathUtility/Vector.cpp +++ b/examples/AndroidMathUtility/Vector.cpp @@ -22,10 +22,10 @@ Vector::Vector(int size) Vector::Vector(const Vector& vec) { if(vec.GetSize() > 0) { - size = vec.GetSize(); - data = new float[size]; + this->size = vec.GetSize(); + this->data = new float[size]; for(int i = 0; i < size; i++) { - data[i] = vec.data[i]; + this->data[i] = vec.data[i]; } } else { @@ -36,8 +36,7 @@ Vector::Vector(const Vector& vec) Vector::~Vector() { - if(data != NULL) - delete[] data; + //delete[] data; } float Vector::Get(int id) const