1

I call a function in C++ from java. In java I have an array of Strings that I want to use in my C++-function.

I have in C++:

 std::string names[6]; // Global variable
 extern "C"
 JNIEXPORT void JNICALL
 Java_com_erikbylow_mycamera3_JNIUtils_updateStandingBoard(JNIEnv *env, jobject type, std::string *names, jint nbrElements){
    memcpy(standingText, names, 6* sizeof(std::string));
    nbrStandText = nbrElements;
}


In `Java`:
public static void updateStanding( String resultArray[]){
    updateStandingBoard(resultArray, resultArray.length);
}

What is the simplest way of achieving what I want? When I try this and different variants it either crashes or yields nonsense data.

2
  • are you looking to convert your c++ code to java? im confused by the question? Commented Jul 16, 2018 at 19:51
  • No, I use C++ in android using the NDK library. But the C++-function is called from Java where I have an array of Strings. Commented Jul 16, 2018 at 19:55

1 Answer 1

3

JNI is a primarily a C API, it doesn't know anything about std::string as you can validate by calling javah on the Java source file contained the native methods declaration.

Also Java isn't C, there is no need to pass the array size as additional parameter.

So your native void updateStandingBoard(String[] result, int size) should actually be native void updateStandingBoard(String[] result)

With this in mind, the JNI code should be

std::vector<std::string> names; // much safer or use std::array as alternative
extern "C"
JNIEXPORT void JNICALL
Java_com_erikbylow_mycamera3_JNIUtils_updateStandingBoard(JNIEnv *env, jobject type, jobjectArray names) {
  jint nbrElements = env->GetArrayLength(names);


  // now copy the strings into C++ world
  for (int i = 0; i < nbrElements ; i++) {
       // access the current string element
       jobject elem = env->GetObjectArrayElement(names, i); 
       jsize length = env->GetStringLength(elem);

       // pin it to avoid GC moving it around during the copy
       const jchar *str = env->GetStringChars(elem, nullptr);


       names.push_back(std::string(str, length));

       // make it available again to the VM 
       env->ReleaseStringChars(elem, str);
  }
}

This was just for the basic strings, if you are interested in UTF strings, then you should make use of std::wstring and the UTF variants of the above JNI functions.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot, I am kind of new to JNI. Thanks for the nice explanation.

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.