c++ - Using non-static objects in jni in java -


i trying learn jni, , wondering how make java object have values associated in jni c++ layer. have java code.

public class test  {     static     {         runtime.getruntime().loadlibrary("jnitests");     }      public native void setvalue(int value);     public native int getvalue();      public static void main(string[] args)      {         test test1 = new test();         test1.setvalue(34);         test test2 = new test();         test2.setvalue(23);         system.out.println(test1.getvalue());     } } 

so trying enable each test object store value in jni using setvalue , getvalue, using c++ code.

#include <jni.h> #include "test.h" int value;  jniexport void jnicall java_test_setvalue(jnienv *, jobject, jint newvalue) { value = newvalue; }  jniexport jint jnicall java_test_getvalue(jnienv *, jobject) { return value; } 

however, problem when use setvalue on test2 , print test1's value has changesd set test2 to. how fix this. tried mapping each jobject int value did not work either.

a possible solution may use of dynamically allocated structure in native code. work, have allocate (for example, in constructor) memory holds structure. address of structure passed java part , stored in java object. then, getvalue , setvalue, parameter added holds memory address of allocated structure, can use storing value. when destroying object, have free memory manually.


using code, native part may like:

#include <cstdlib> #include <jni.h> #include "test.h"  struct data {     int value; };  jniexport void jnicall java_test_setvalue0(jnienv *, jobject, jlong address, jint newvalue) {     struct data *ptr = (struct data *)address;     ptr->value = newvalue; }  jniexport jint jnicall java_test_getvalue0(jnienv *, jobject, jlong address) {     struct data *ptr = (struct data *)address;     return ptr->value; }  jniexport jlong jnicall java_test_construct0(jnienv *, jobject) {     struct data *ptr = (struct data *)malloc(sizeof(*ptr));     return (jlong)ptr; }  jniexport void jnicall java_test_destruct0(jnienv *, jobject, jlong address) {     struct data *ptr = (struct data *)address;     free(ptr); } 

and java part like:

public class test  {     static     {         runtime.getruntime().loadlibrary("jnitests");     }      private long address;      private native long construct0();     private native void destruct0(long address);     private native void setvalue0(long address, int value);     private native int getvalue0(long address);      public test() {         this.address = this.construct0();     }      @override     public void finalize() {         this.destruct0(this.address);         super.finalize();     }      public void setvalue(int value) {         this.setvalue0(this.address, value);     }      public int getvalue() {         return this.getvalue0(this.address);     }      public static void main(string[] args)      {         test test1 = new test();         test1.setvalue(34);         test test2 = new test();         test2.setvalue(23);         system.out.println(test1.getvalue());     } } 

i renamed native methods introduce address parameter without api change.


Comments

Popular posts from this blog

java.util.scanner - How to read and add only numbers to array from a text file -

rewrite - Trouble with Wordpress multiple custom querystrings -