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

帅比萌擦擦* 提交于 2019-11-28 21:54:07
da_petcu21

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);
}
Sdra

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.

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.

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!