android - 在 Android NDK 中从 C++ 代码直接调用另一个 .so 文件中的函数

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

我有 a.so 定义了 void a()b.so 定义了 void b()。它们都放在 .apk 中,因此可供 Android 应用程序使用。

现在假设我通过 JNI 调用 a()。是否可以在完全绕过 JNI 的情况下从 a() 调用 b()

我在Android中可以这样做吗(代码只是为了说明,所以可能会有一些错误)?

void a() {
    void *handle = dlopen("b.so", RTLD_LAZY);
    void (*b)() = dlsym(handle, "b");
    b();
}

我是否需要添加完全限定路径,或者 b.so 是否已经在应用程序的 LD_LIBRARY_PATH 中?

最佳答案

您可以在 Android 上这样做,但要注意共享库在 Android 文件夹中的位置。它可以从一个版本更改为另一个版本。 例如,在 api 17 上,它保留在/data/app-lib/中。您可以硬写它,但最好是调用 Java(通过 JNI)以了解库应该位于何处。 我们正在我们的项目中做这样的事情:

JNIEnv* env;
const char* temp;

jobject oActivity = state->activity->clazz;
jclass cActivity = env->GetObjectClass(oActivity);

// get the path to where android extracts native libraries to
jmethodID midActivityGetApplicationInfo = env->GetMethodID(cActivity, "getApplicationInfo", "()Landroid/content/pm/ApplicationInfo;");
jobject oApplicationInfo = env->CallObjectMethod(oActivity, midActivityGetApplicationInfo);
jclass cApplicationInfo = env->GetObjectClass(oApplicationInfo);
jfieldID fidApplicationInfoNativeLibraryDir = env->GetFieldID(cApplicationInfo, "nativeLibraryDir", "Ljava/lang/String;");
jstring sNativeLibraryDir = (jstring)env->GetObjectField(oApplicationInfo, fidApplicationInfoNativeLibraryDir);
temp = env->GetStringUTFChars(sNativeLibraryDir, NULL);
strcpy(libpath, temp);
strcat(libpath, "/");

然后你在战斗中使用你的 dlopen + dlsym 组合,它应该可以工作。

关于android - 在 Android NDK 中从 C++ 代码直接调用另一个 .so 文件中的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30368096/

相关文章:

安卓NDK : calling java method from JNI C class

android - 如果用户修改了一个值,则在所有应用程序上实时更改

android - 在 Google map 上使用 OSM 路由

android - onActivityResult() 启用蓝牙和发现后的错误结果代码

c++ - 如何多次发送SIGINT信号

android - 从 ANativeWindow_Buffer 获取 ANativeWindowBuffer

java.lang.ClassCastException : android. os.BinderProxy 无法转换为 com.leonard.sg.okcoin.service.SyncAndTradeService$SyncAndTradeBinder

C++:如何将模板数组声明为函数参数

c++ - 可以替换 std::allocator 允许 std::set 使用 void* 和单独的复制/释放函数吗?

android - UnsatisfiedLinkError: 无法加载 cocos2dcpp: findLibrary 返回 null