我可以使用System.loadLibrary(lib);
在android java中加載我的共享庫並使用它。目前這種方法的問題是我實際上可以運行兩個我的android應用程序的實例。使用dlopen()代替system.loadlib的Android JNI
讓我的應用程序有兩個實例與一個共享庫不一樣。我需要共享庫的兩個實例。好的新功能是,從java中我可以發現是否運行實例A或實例B.有時我會在實例A中運行,但仍然必須加載實例B;這樣做完全混淆了第一例。
我到目前爲止所做的是找出我正在運行哪個實例,然後將其傳遞給JNI,然後在我的.c文件中加載.so與dlopen,現在我有一個處理我的共享庫。
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);
android編譯LM_ID_NEWLM
拋出LM_ID_NEWLM
未聲明(首次使用此功能)。
於是,我根據使用RTLD_LOCAL上this question
我編譯這個項目時,目前沒有得到任何錯誤。
我現在的問題是,如何從c代碼中加載這些庫文件?
'if(lib == 0)'?不應該是'if(mainHandle == NULL)'或'if(sdlHandle == NULL)'嗎?並會加載兩次幫助?根據http://man7.org/linux/man-pages/man3/dlopen.3.html:「如果使用dlopen()再次加載相同的共享對象,則返回相同的對象句柄。」 –
libe == 0是我粘貼一些代碼時的一種類型。根據您提供的標誌RTLD_LOCAL的鏈接「在此共享的 對象中定義的符號不可用於解決隨後加載的共享對象中的引用。」 「。它基本上把共享庫視爲一個靜態的每個調用,除非我錯了,我可能是這樣。 – user1610950
目前還不清楚你想要完成什麼。如果有兩個應用程序實例在不同的進程中運行,它們都可以加載相同的庫並且不會互相干擾。直接使用'dlopen()'並沒有什麼不同於'loadLibrary()'。你是否試圖在同一個進程中擁有同一共享庫*的兩個不同副本*?如果是這樣......爲什麼?這是一個設計不佳的圖書館,裏面有很多全球性的圖書館嗎? – fadden