Problem returning string from native

110 views
Skip to first unread message

chrisoz

unread,
Aug 17, 2009, 11:26:31 AM8/17/09
to android-ndk
The following code in native function causes my application to stop in
the emulator. I simply want a function to convert a byte[] to a Java
String (The built-in Java function String(g_buffer, "Cp1252") took 5-6
seconds on a 20K byte array, even more on an actual device). However -
it works if I cast only 200 bytes from _buf1 (not 300). I can't figure
out what's wrong with this, would appreciate some advice. I guess it
could have to do with the handling of the java buffer pointers, but
after extensive googling I still haven't found any good practical
examples on how to do this.

Java_mypackage_NativeLib_getConvertString
(JNIEnv * env, jobject obj, jobject indata)
{
jbyte* _buf1;
char* msg;
int counter;
msg=(char*)malloc(60000);
_buf1 = (*env)->GetByteArrayElements(env, indata, NULL);

for (counter=0;counter<300;++counter)
{
msg[counter]=(char)_buf1[counter];
}

(*env)->ReleaseByteArrayElements(env, indata, _buf1, JNI_ABORT);
return (*env)->NewStringUTF(env, msg);
free(msg);
}

fadden

unread,
Aug 17, 2009, 4:40:40 PM8/17/09
to android-ndk
On Aug 17, 8:26 am, chrisoz <kristian.aus...@gmail.com> wrote:
> I simply want a function to convert a byte[] to a Java
> String
[...]
> Java_mypackage_NativeLib_getConvertString
> (JNIEnv * env, jobject obj, jobject indata)
> {
>         jbyte* _buf1;
>         char* msg;
>         int counter;
>         msg=(char*)malloc(60000);
>         _buf1 = (*env)->GetByteArrayElements(env, indata, NULL);
>
>         for (counter=0;counter<300;++counter)
>         {
>                 msg[counter]=(char)_buf1[counter];
>         }
>
>         (*env)->ReleaseByteArrayElements(env, indata, _buf1, JNI_ABORT);
>         return (*env)->NewStringUTF(env, msg);
>         free(msg);

I don't see an obvious crashing problem here. However:

(1) What does the logcat output show?
(2) You probably want GetByteArrayRegion(array, start, length, buffer)
rather than get/copy/release. (See also the Region Calls section in
jni-tips.html.)
(3) Note that "msg" isn't freed, since you're returning before
reaching that line.

chrisoz

unread,
Aug 18, 2009, 10:51:09 AM8/18/09
to android-ndk
Thank you for your points fadden!

I eventually discovered the return of NewStringUTF crashes the
application when msg contained a scandinavian character (ASCII>127). I
made my own "quick and dirty" function to convert full 256-ASCII to
Java Unicode (to fulfill my needs, anyway). 60K sting inn < 1 sec. If
anyone can have a use for it let me know.

(1) I haven't worked out how to produce log output in eclipse. I
downloaded the LogView plugin but couldn't make it work, for now... I
guess it could be useful as error tracing is extremely hard without
it.
(2) I will look into this, thank you
(3) Thank you for identifying this memory leak, better off using a
static variable that malloc/free.

Chris
> reaching that line.- Hide quoted text -
>
> - Show quoted text -

fadden

unread,
Aug 18, 2009, 4:05:33 PM8/18/09
to android-ndk
On Aug 18, 7:51 am, chrisoz <kristian.aus...@gmail.com> wrote:
> I eventually discovered the return of NewStringUTF crashes the
> application when msg contained a scandinavian character (ASCII>127). I
> made my own "quick and dirty" function to convert full 256-ASCII to
> Java Unicode (to fulfill my needs, anyway). 60K sting inn < 1 sec. If
> anyone can have a use for it let me know.

Is the string legal UTF-8? If you're running with CheckJNI enabled,
illegal sequences will cause a rejection message from the VM, followed
shortly thereafter by a VM abort.

> (1) I haven't worked out how to produce log output in eclipse. I
> downloaded the LogView plugin but couldn't make it work, for now... I
> guess it could be useful as error tracing is extremely hard without
> it.

If you have adb running, "adb logcat" will suffice. If you don't have
adb running, I'm impressed you got this far. :-)
Reply all
Reply to author
Forward
0 new messages