java - Char* Corrupted Across JNI Calls -


i'm working c library (librtmp) on android (google glass specifically), bindings created swig.

when call native method struct containing char*, return method, , call native method, char* not have same data in it, many times data appear null, contain parts of java or project path or random text (ex: glassvideostreamer/libr, zunk+, sun/* ) contain non-valid unicode code points. pointer keeps pointing same memory location between jni calls, , correct when first native method exits, , corrupted when enters native method.

wrapping both methods in native function , calling function works correctly, when calling native method data no longer @ memory location.

here's code:

test.i

%module test_wrapper #define no_crypto /* in following section added verbatim .cxx wrapper file*/ %{ #include "rtmp.h" %} test* alloc_test(); void init_test(test* t, char* data, int len); void test_string(test* t); void init_and_test_string(test* t, char* data, int len); 

rtmp.h

  typedef struct test {     char* data;     int len;   } test;   test* alloc_test();   void init_test(test* t, char* data, int len);   void test_string(test* t);   void init_and_test_string(test* t, char* data, int len); 

rtmp.c

test* alloc_test(){   return calloc(sizeof(test)); } void init_test(test* t, char* data, int len){   t->data = data;   t->len = len;   __android_log_print(android_log_debug,"test", "string: %.*s  (pointer: %p)", t->len, t->data, t); } void test_string(test* t){  __android_log_print(android_log_debug,"test","%string: %.*s  (pointer: %p)", t->len, t->data, t); } void init_and_test_string(test* t, char* data, int len){   init_test(t, data, len);   test_string(t); } 

finally (for c) here's generated swig bindings librtmp_wrap.c

swigexport jlong jnicall java_atellis_glassvideostreamer_librtmp_test_1wrapperjni_alloc_1test(jnienv *jenv, jclass jcls) {   jlong jresult = 0 ;   test *result = 0 ;    (void)jenv;   (void)jcls;   result = (test *)alloc_test();   *(test **)&jresult = result;    return jresult; }   swigexport void jnicall java_atellis_glassvideostreamer_librtmp_test_1wrapperjni_init_1test(jnienv *jenv, jclass jcls, jlong jarg1, jstring jarg2, jint jarg3) {   test *arg1 = (test *) 0 ;   char *arg2 = (char *) 0 ;   int arg3 ;    (void)jenv;   (void)jcls;   arg1 = *(test **)&jarg1;    arg2 = 0;   if (jarg2) {     arg2 = (char *)(*jenv)->getstringutfchars(jenv, jarg2, 0);     if (!arg2) return ;   }   arg3 = (int)jarg3;    init_test(arg1,arg2,arg3);   if (arg2) (*jenv)->releasestringutfchars(jenv, jarg2, (const char *)arg2); }   swigexport void jnicall java_atellis_glassvideostreamer_librtmp_test_1wrapperjni_test_1string(jnienv *jenv, jclass jcls, jlong jarg1) {   test *arg1 = (test *) 0 ;    (void)jenv;   (void)jcls;   arg1 = *(test **)&jarg1;    test_string(arg1); }   swigexport void jnicall java_atellis_glassvideostreamer_librtmp_test_1wrapperjni_init_1and_1test_1string(jnienv *jenv, jclass jcls, jlong jarg1, jstring jarg2, jint jarg3) {   test *arg1 = (test *) 0 ;   char *arg2 = (char *) 0 ;   int arg3 ;    (void)jenv;   (void)jcls;   arg1 = *(test **)&jarg1;    arg2 = 0;   if (jarg2) {     arg2 = (char *)(*jenv)->getstringutfchars(jenv, jarg2, 0);     if (!arg2) return ;   }   arg3 = (int)jarg3;    init_and_test_string(arg1,arg2,arg3);   if (arg2) (*jenv)->releasestringutfchars(jenv, jarg2, (const char *)arg2); } 

on java side: have generated swigtype_p test wraps struct pointer , code calls jni functions: test_wrapperjni.java

public class test_wrapperjni {   public final static native long alloc_test();   public final static native void init_test(long jarg1, string jarg2, int jarg3);   public final static native void test_string(long jarg1);   public final static native void init_and_test_string(long jarg1, string jarg2, int jarg3); } 

and test_wrapper.java

public class test_wrapper {   public static swigtype_p_test alloc_test() {     long cptr = test_wrapperjni.alloc_test();     return (cptr == 0) ? null : new swigtype_p_test(cptr, false);   }    public static void init_test(swigtype_p_test t, string data, int len) {     test_wrapperjni.init_test(swigtype_p_test.getcptr(t), data, len);   }    public static void test_string(swigtype_p_test t) {     test_wrapperjni.test_string(swigtype_p_test.getcptr(t));   }    public static void init_and_test_string(swigtype_p_test t, string data, int len) {     test_wrapperjni.init_and_test_string(swigtype_p_test.getcptr(t), data, len);   }  } 

putting get:

system.loadlibrary("test"); swigtype_p_test test = test_wrapper.alloc_test(); test_wrapper.init_test(test, "will string stay same?", 31); test_wrapper.test_string(test);  test = test_wrapper.alloc_test(); test_wrapper.init_and_test_string(test, "this string stay same", 30); 

which gets result (in logcat):

05-11 12:27:33.198    4568-4568/atellis.glassvideostreamer d/dalvikvm﹕ trying load lib /data/app-lib/atellis.glassvideostreamer-1/libtest.so 0x41b597b0 05-11 12:27:33.198    4568-4568/atellis.glassvideostreamer d/dalvikvm﹕ added shared lib /data/app-lib/atellis.glassvideostreamer-1/libtest.so 0x41b597b0 05-11 12:27:33.198    4568-4568/atellis.glassvideostreamer d/dalvikvm﹕ no jni_onload found in /data/app-lib/atellis.glassvideostreamer-1/libtest.so 0x41b597b0, skipping init 05-11 12:27:38.128    4568-4568/atellis.glassvideostreamer d/test﹕ string: string stay same?  (pointer: 0x59564088) 05-11 12:27:39.940    4568-4568/atellis.glassvideostreamer d/test﹕ string:   (pointer: 0x59564088) 05-11 12:27:41.261    4568-4568/atellis.glassvideostreamer d/test﹕ string: string stay same  (pointer: 0x59565948) 05-11 12:27:41.261    4568-4568/atellis.glassvideostreamer d/test﹕ string: string stay same  (pointer: 0x59565948) 

in case string becomes blank! mentioned above though, sometime contain file paths or random text.

typedef struct test {     char* data;     int len; } test; 

this specifies no space store the string data, merely pointer hold address.

you seem in practice pointing @ memory of various function arguments of temporary reservation, , not work memory can re-purposed later.

void init_test(test* t, char* data, int len){     t->data = data; 

in fact, explicitly release claim memory:

init_and_test_string(arg1,arg2,arg3);  if (arg2) (*jenv)->releasestringutfchars(jenv, jarg2, (const char *)arg2); 

you must explicitly reserve memory hold string, , copy temporary storage there.


Comments

Popular posts from this blog

android - MPAndroidChart - How to add Annotations or images to the chart -

javascript - Add class to another page attribute using URL id - Jquery -

firefox - Where is 'webgl.osmesalib' parameter? -