0

I'm having issues trying to convert an unsigned char array to jstring.

The context is I'm using a shared c library from Java. So I'm implementing a JNI c++ file. The function I use from the library returs a unsigned char* num_carte_transcode

And the function I implemented in the JNI C++ file returns a jstring.

So I need to convert the unsigned char array to jstring.

I tried this simple cast return (env)->NewStringUTF((char*) unsigned_char_array);

But though the array should only contain 20 bytes, I get randomly 22 or 23 bytes in Java... (Though the 20 bytes are correct)

EDIT1: Here some more details with example

JNIEXPORT jstring JNICALL Java_com_example_demo_DemoClass_functionToCall
  (JNIEnv *env, jobject, ) {
  // Here I define an unsigned char array as requested by the library function
  unsigned char unsigned_char_array[20];
  // The function feeds the array at execution
  function_to_call(unsigned_char_array);

  // I print out the result for debug purpose
  printf("result : %.*s (%ld chars)\n", (int) sizeof unsigned_char_array, unsigned_char_array, (int) sizeof unsigned_char_array);

  // I get the result I want, which is like: 92311221679609987114 (20 numbers)

  // Now, I need to convert the unsigned char array to jstring to return to Java
  return (env)->NewStringUTF((char*) unsigned_char_array);
  // Though... On debugging on Java, I get 21 bytes 92311221679609987114 (check the image below)
}

enter image description here

And sometimes I get 22 bytes, sometimes 23 ... though the expected result is always 20 bytes.

3
  • UTF-8 should be passed. As one java char or int code point can be more than 1 byte. Is the unsigned char* indeed 20 bytes long, and is the java char[] 20 long, that is 40 bytes, or what is exactly happening? There should probably be no problem with 7 bits ASCII. Commented Jun 27, 2022 at 14:37
  • Hello @JoopEggen. thanks for your quick reply. I edited the intial question to add more details :) Commented Jun 27, 2022 at 14:47
  • Please use text instead of images. See meta.stackoverflow.com/questions/285551/… for more details on the reason. Kindly share the input and the result as an array in text. Commented Jun 27, 2022 at 14:54

1 Answer 1

2

The string passed to NewStringUTF must be null-terminated. The string you're passing, however, is not null-terminated, and it looks like there's some garbage at the end of the string before the first null.

I suggest creating a larger array, and adding a null terminator at the end:

JNIEXPORT jstring JNICALL Java_com_example_demo_DemoClass_functionToCall
  (JNIEnv *env, jobject recv) {
  unsigned char unsigned_char_array[20 + 1]; // + 1 for null terminator
  function_to_call(unsigned_char_array);    
  unsigned_char_array[20] = '\0'; // add null terminator

  printf("result : %s (%ld chars)\n", unsigned_char_array, (int) sizeof unsigned_char_array);

  return (env)->NewStringUTF((char*) unsigned_char_array); // should work now
}
Sign up to request clarification or add additional context in comments.

2 Comments

Alright, that was it ! Thanks very much for your help :)
Something to note: NewStringUTF() expects modified UTF-8, so if function_to_call() outputs standard UTF-8 then NewStringUTF() won't work correctly for Unicode codepoint U+0000 or codepoints > U+FFFF. JNI doesn't have any functions that handle standard UTF-8, but you can use JNI to call a String constructor that accepts standard UTF-8 (this would also allow you to specify the actual byte count so you don't have to worry about the null terminator).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.