Search code examples
androidandroid-ndkpjsippjsua2

UnsatisfiedLinkError when run System.loadLibrary


I am using pjsip library through android ndk. I used Android NDK 16 to compile pjsip. One user (HTC One, Android 5.0.2) faced a lot of crashes while trying to start our project. This is the error:

 Fatal Exception: java.lang.UnsatisfiedLinkError
dlopen failed: cannot locate symbol "stdin" referenced by "libpjsua2.so"...
... .PjSipApp.<clinit>

In the project we have .so-files for 4 abis, as stated in google android ndk official docs: arm64-v8a, armeabi-v7a, x86, x86_64. Here is how I load libraries in code:

public class PjSipApp {
    private static final String TAG = "Pjsua-PjSipApp";

    static {
        try {
            System.loadLibrary("openh264");
            System.loadLibrary("yuv");
        } catch (UnsatisfiedLinkError ignore) {
        }
        System.loadLibrary("pjsua2");
        Log.v(TAG, "LibraryLoaded");
    }...

So System.loadLibrary("pjsua2"); throws this UnsatisfiedLinkError. Maybe anyone knows, what is the reason for this?


Solution

  • You probably compiled binaries with a higher API Level.

    This is how they are defined in stdio.h

    #if __ANDROID_API__ >= 23
    extern FILE* stdin __INTRODUCED_IN(23);
    extern FILE* stdout __INTRODUCED_IN(23);
    extern FILE* stderr __INTRODUCED_IN(23);
    /* C99 and earlier plus current C++ standards say these must be macros. */
    #define stdin stdin
    #define stdout stdout
    #define stderr stderr
    #else
    /* Before M the actual symbols for stdin and friends had different names. */
    extern FILE __sF[] __REMOVED_IN(23);
    #define stdin (&__sF[0])
    #define stdout (&__sF[1])
    #define stderr (&__sF[2])
    #endif
    

    So, if you built for API level >= 23, the symbol will resolve to File* stdin which doesn't exist in API < 23. I'd suggest to reduce the API level.