Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android JNI doesn't find C++ standard library header files

I am following the android-studio-jni guide and trying to compile C++ native code with gradle. Everything works great: I can load the JNI function, write C++ classes, compile, run and debug. And I don't need to write and maintain the Application.mk and Android.mk makefiles; both of them seems to be handled by gradle implicitly. There is only one thing that I don't understand: How to include C++ header files from the standard libraries?

I think I must have missed something in the gradle script, but I cannot find a good reference about what to add here. Here is the script:

android.ndk {
    moduleName = "hello-android-jni"

    // I tried adding the following, but nothing happens
    stl = "stlport_static"
}

And screenshots showing that all the std headers are not visible.

enter image description here enter image description here

like image 866
Yuchen Avatar asked Oct 30 '22 08:10

Yuchen


1 Answers

There are things needed to do in order make it work:

  • Change the file extension from .c to .cpp so that ndk will compile the file with g++ instead of gcc.
  • Add stl configuration such as stl = "stlport_static", other options are gnustl_static, system and etc. I haven't tried them all but I guess it doesn't really matter if you are using some basic stuff such as std::string.

  • Click of the sync button as indicated in the screenshot below. The getcha is that even if it says finish syncing, it will take some extra time to index the file and locate the header from stl. So be patient, don't rush. Be patient, don't rush. It take roughly about 10s for me. If you cannot find this sync on you menu bar, it is also available under Tools > Android > Sync Poroject with Gradle Files.

    enter image description here

  • Lastly, update the code to C++ and test it out:

    #include <jni.h>
    #include <iostream>
    
    extern "C" {
    
    JNIEXPORT jstring JNICALL
    Java_com_yuchen_helloandroidjni_MainActivity_getMsgFromJni(JNIEnv *env, jobject instance) {
    
        // TODO
        std::string message = "Hello World From Jni";
    
        return env->NewStringUTF(message.c_str());
    }
    }
    

Now it should works seamlessly. Go native, yeah!


Edit:

I don't know exactly what we need to put the code under extern "C" { ... }. But it seems it is important, otherwise, we will have error:

java.lang.UnsatisfiedLinkError: No implementation found for void com.yuchen.helloandroidjni.getMsgFromJni() (tried Java_com_yuchen_helloandroidjni_MainActivity_getMsgFromJni)

If someone any explain this.

like image 158
Yuchen Avatar answered Nov 11 '22 11:11

Yuchen