Can't load native shared library with dependencies in a native activity app
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@[email protected]"), "ANativeActivity_onCreate");
if (!main)
{
LOGE("undefined symbol ANativeActivity_onCreate");
exit(1);
}
main(app, ud, udsize);
}
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.