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
Post a Comment