我有 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/