Android JNI 使用 dlopen() 代替 system.loadlib

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

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

我的应用程序有两个实例和一个共享库则不然。我需要共享库的两个实例。好消息是,我可以从 java 中找出我正在运行实例 A 还是实例 B。有时我会在实例 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");
    }

}

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

dlmopen(LM_ID_NEWLM, "path/to/lib", RTLD_NOW | RTLD_LOCAL);

在 android 上使用 LM_ID_NEWLM 进行编译抛出 LM_ID_NEWLM未声明(在此函数中首次使用)。

所以我尝试使用基于this question的RTLD_LOCAL

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

我现在的问题是,从 C 代码加载这些库后,我如何实际使用它们?

最佳答案

不,如果您不使用 System.loadLibrary() 或等效函数,则无法使用 JNI。

关于Android JNI 使用 dlopen() 代替 system.loadlib,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32778853/

相关文章:

c - 计算阶乘 (n)%m 的递归方法中的段错误

android - 在指定位置找不到 NDK

android - 如何在android中使用ffmpeg文件从URI播放音频文件

Android:你如何让按钮在一段时间内不可点击?

java - 从非 Activity 中使用 startActivityForResult

android - 使用另一个库项目作为外部依赖编译 gradle 库项目

C - 拆分降低了我的计算机速度

c - A/C编译器是否在编译时执行移位操作?

适用于 x86_64 的 Android NDK 没有 bcopy 和索引引用

android - 为 ARM/Android 交叉编译大型 C++ 项目 - 问题和注意事项