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 formstatic int obj_cnt;
isn't threadsafenativeobjclass *nobj_lst;
should static membernativeobjclass *nobj_lst;
should std::vectorlong nobj_lst_size=0;
should static memberlong nobj_lst_size=0;
should of typesize_t
nativeobjclass nobj;
creates object - it's not referencenobj_lst=(nativeobjclass*)calloc(nobj_lst_size,sizeof(nativeobjclass));
plain wrong. usenew[]
if have use manually managed array,std::vector
still betternobj_lst[nobj_lst_size-1]=nobj
copies object creatednativeobjclass 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
Post a Comment