java - Holding reference to native class object in JNI -


i trying create c++ class , hold objects array, , reference c++ objects java using jni, since jni not provide mechanism hold non primitive type of objects java.

i have implemented code mentioned below output showing me if multiple objects have got created , receiving heap error on second call create new native object.

can this?

thanks

codes:

java class(the function loading library dll has been defined in libobj):

package org.jnp.pkg004;  import org.jnp.libloader.libobj;  public class purecppobjfactory extends libobj {      private long cppobjlstsz;      public purecppobjfactory() {         super();         cppobjlstsz=0;     }      public native void newcppobj();      public native void printcppobjdetails(long cppobjlstindex);  } 

c++ library code:

#include "stdafx.h" #include "stdlib.h" #include <iostream> #include <iomanip> #include <stdio.h>  using namespace std;  #include "org_jnp_pkg004_purecppobjfactory.h"  class nativeobjclass {     private:         int num_ran;         int obj_num;     public:         static int obj_cnt;         nativeobjclass()         {             obj_cnt++;             obj_num=obj_cnt;             num_ran=rand();             cout<<"native object number "<<setfill('0')<<setw(5)<<obj_cnt<<" random number:"<<num_ran<<endl;             }          int get_obj_num()         {             return obj_num;         }          int get_num_ran()         {             return num_ran;         } };  int nativeobjclass::obj_cnt=0;  nativeobjclass *nobj_lst; long nobj_lst_size=0;  jniexport void jnicall java_org_jnp_pkg004_purecppobjfactory_newcppobj   (jnienv *env, jobject obj) {      jclass thiscls = env->getobjectclass(obj);     jfieldid fid=env->getfieldid(thiscls,"cppobjlstsz","j");         nativeobjclass nobj;      jlong java_lst_sz=env->getlongfield(obj,fid);         nativeobjclass *temp_nobj_lst;     temp_nobj_lst=new nativeobjclass[nobj_lst_size];     if(nobj_lst_size>0)     {         memmove(temp_nobj_lst,nobj_lst,nobj_lst_size);         delete nobj_lst;     }        nobj_lst_size++;     nobj_lst=new nativeobjclass[nobj_lst_size];     if(nobj_lst_size>1)     {         memmove(nobj_lst,temp_nobj_lst,nobj_lst_size);         delete temp_nobj_lst;     }     nobj_lst[nobj_lst_size]=nobj;     java_lst_sz++;      env->setlongfield(obj,fid,java_lst_sz);  }   jniexport void jnicall java_org_jnp_pkg004_purecppobjfactory_printcppobjdetails   (jnienv *env, jobject obj, jlong indx) {     nativeobjclass nobj=nobj_lst[indx];     cout<<"retrieved native object number "<<setfill('0')<<setw(5)<<nobj.get_obj_num()<<" random number:"<<nobj.get_num_ran()<<endl; } 

class containing main:

package test.jnp.pkg004;  import org.jnp.pkg004.purecppobjfactory;  public class purecppobjfactorytest {      public static void main(string[] args) {          purecppobjfactory pcf=new purecppobjfactory();         pcf.newcppobj();         pcf.printcppobjdetails(0);         pcf.newcppobj();         //pcf.newcppobj();      }  } 

output:

native object number 00001 random number:41 native object number 00002 random number:18467 retrieved native object number 00002 random number:18467 native object number 00003 random number:6334 native object number 00004 random number:26500 

also getting heap error popup after code executes

ok, here's list of issues seen @ first glance:

  • using namespace std; bad form
  • static int obj_cnt; isn't threadsafe
  • nativeobjclass *nobj_lst; should static member
  • nativeobjclass *nobj_lst; should std::vector
  • long nobj_lst_size=0; should static member
  • long nobj_lst_size=0; should of type size_t
  • nativeobjclass nobj; creates object - it's not reference
  • nobj_lst=(nativeobjclass*)calloc(nobj_lst_size,sizeof(nativeobjclass)); plain wrong. use new[] if have use manually managed array, std::vector still better
  • nobj_lst[nobj_lst_size-1]=nobj copies object created
  • nativeobjclass nobj=nobj_lst[indx]; makes pointless copy of array object

consider approach instead. note below code has not been tested or compiled, it's display idea.

public class cppobject {      private long handle;      public cppobject() {         handle = createnativeobject();     }      public void cleanup() {         deletenativeobject(handle);         handle = 0;     }      private static native long createnativeobject();     private static native void deletenativeobject(long handle);     private static native void printobjectdetails(long handle);       public void printobjdetails() {         printobjectdetails(handle);     }  }     jniexport jlong jnicall whatever_createnativeobject(jnienv *env, jobject obj) {     return reinterpret_cast<jlong>(new cppobject()); }  jniexport void jnicall whatever_deletenativeobject(jnienv *env, jobject obj, jlong handle) {     delete reinterpret_cast<cppobject *>(handle); }  jniexport void jnicall printobjectdetails(jnienv *env, jobject obj, jlong handle) {     reinterpret_cast<cppobject *>(handle)->printdetails(); } 

a java long 64 bits, above code should work fine on both 32 , 64-bit platforms.


Comments

Popular posts from this blog

java - WrongTypeOfReturnValue exception thrown when unit testing using mockito -

php - Magento - Deleted Base url key -

android - How to disable Button if EditText is empty ? -