Android JNI使用dlopen()而不是system.loadlib

时间:2015-09-25 09:19:09

标签: android c android-ndk java-native-interface dlopen

我可以使用System.loadLibrary(lib);在android java中加载我的共享库并使用它。这种当前方法的问题是我实际上可以运行两个我的android应用程序实例。

我的应用程序有两个共享库的实例并不是。我需要两个共享库的实例。好的新东西是从java我可以看出我是在运行实例A还是实例B.有时我会在实例A中运行但仍然需要加载实例B;这样做完全搞砸了第一个例子。

我到目前为止所做的是找出我正在运行的实例并将其传递给JNI然后在我的.c文件中我用dlopen加载.so,现在我有了一个共享库的句柄。

java方面:

        if(preview)
        {
            for (String lib : getLibraries()) {
                   nativeInitPreview(lib);
                }
        }
        else
        {
            for (String lib : getLibraries()) {
                nativeInitLive(lib);
                }
        }

c代码方:

static void *mainHandleLive = NULL;
static void *SDLHandleLive = NULL;

JNIEXPORT int JNICALL Java_org_libsdl_app_SDLActivity_nativeInitLive(JNIEnv* env, jobject instance, jstring lib)
{
    const char *libString = (*env)->GetStringUTFChars(env, lib, NULL);
    __android_log_print(ANDROID_LOG_INFO, "SDL", "Java_org_libsdl_app_SDLActivity_nativeInitLive %s", libString);
    (*env)->ReleaseStringUTFChars(env, lib, libString);

    mainHandleLive = dlopen("/data/app-lib/org.libsdl.app-1/libmain.so", RTLD_NOW | RTLD_LOCAL);
    if (mainHandleLive == 0)
    {
        __android_log_print(ANDROID_LOG_INFO, "SDL", "/data/app-lib/org.libsdl.app-1/libmain.so failed to open");
    }
    SDLHandleLive = dlopen("/data/app-lib/org.libsdl.app-1/libSDL2.so", RTLD_NOW | RTLD_LOCAL);
    if (SDLHandleLive == 0)
    {
        __android_log_print(ANDROID_LOG_INFO, "SDL", "/data/app-lib/org.libsdl.app-1/libSDL2.so failed to open");
    }

}

我有两个问题,引导我这个想法的最初帖子使用了这样的函数原型:

dlmopen(LM_ID_NEWLM, "path/to/lib", RTLD_NOW | RTLD_LOCAL);
使用LM_ID_NEWLM进行android编译时,

会抛出LM_ID_NEWLM未声明(在此函数中首次使用)。

所以我尝试使用基于this question

的RTLD_LOCAL

编译此项目时,我目前没有遇到任何错误。

我现在的问题是,如果从c代码加载这些库,我该如何实际使用这些库?

1 个答案:

答案 0 :(得分:0)

如果您不使用System.loadLibrary()或同等版本,则不能使用JNI。