Can't load native shared library with dependencies in a native activity app

后端 未结 4 1930
心在旅途
心在旅途 2020-12-15 00:19

In my Android app I have 4 libraries:

libTemplate.so
   depends on libPorkholt.so
libPorkholt.so
   depends on libpng15.so
   depends on liblua.so
   depends         


        
相关标签:
4条回答
  • 2020-12-15 01:11

    I don't think Android will automatically load libraries other than the ones specified in the manifest, so you should create a "dummy" Java class to load external dependencies, it should contain:

    static {
        System.loadLibrary("openal");
        System.loadLibrary("lua");
        System.loadLibrary("png15");
        System.loadLibrary("Porkholt");
        System.loadLibrary("Template");
    }
    

    Since this section is static, it will be executed when the class is loaded, even if its methods aren't called.

    0 讨论(0)
  • 2020-12-15 01:13

    Your Activity probably has a static constructor that calls System.Load("libTemplate.so"). It should load the other libraries according to the dependency order.

    0 讨论(0)
  • 2020-12-15 01:17

    This no longer affects API 24+ (see the framework fix here). However, if you need to support older versions, extend NativeActivity, refer to your extension in the manifest file instead, and add the static block mentioned in Sdra's answer as workaround.

    0 讨论(0)
  • 2020-12-15 01:22

    Since apparently Android isn't smart enough to set a LD_LIBRARY_PATH correctly, I managed to solve my problem by creating a small bootstrapper library that manually loads the actual activity. Here's the code:

    #include <android/native_activity.h>
    #include <android/log.h>
    #include <dlfcn.h>
    #include <errno.h>
    #include <stdlib.h>
    
    #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "Porkholt", __VA_ARGS__))
    #define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "Porkholt", __VA_ARGS__))
    
    #define LIB_PATH "/data/data/@PH_BUNDLE_ID@/lib/"
    
    void * load_lib(const char * l)
    {
        void * handle = dlopen(l, RTLD_NOW | RTLD_GLOBAL);
        if (!handle)
        {
            LOGE("dlopen(\"%s\"): %s", l, strerror(errno));
            exit(1);
        }
        return handle;
    }
    
    void ANativeActivity_onCreate(ANativeActivity * app, void * ud, size_t udsize)
    {
        LOGI("Loaded bootstrap");
        load_lib(LIB_PATH "libpng15.so");
        load_lib(LIB_PATH "liblua.so");
        load_lib(LIB_PATH "libopenal.so");
        load_lib(LIB_PATH "libPorkholt.so");
        void (*main)(ANativeActivity*, void*, size_t) = dlsym(load_lib(LIB_PATH "lib@PH_APP_TARGET@.so"), "ANativeActivity_onCreate");
        if (!main)
        {
            LOGE("undefined symbol ANativeActivity_onCreate");
            exit(1);
        }
        main(app, ud, udsize);
    }
    
    0 讨论(0)
提交回复
热议问题