7

私のネイティブ C++ プロジェクトでは、構成を使用して起動時にクライアント側で変更できる、プリコンパイル済み共有ライブラリのランタイム ロードをセットアップしました。Androidでdlopenを呼び出す適切な方法は何ですか? 次のように Android.mk ファイルでこのライブラリをプリコンパイル済みライブラリとして定義しないと、dlopen は共有ライブラリを開くことができません。

LOCAL_PATH := $(call my-dir)

LOCAL_CFLAGS += -DDEBUG 
LOCAL_CFLAGS += -DANDROID 

include $(CLEAR_VARS)
LOCAL_MODULE := bar
LOCAL_SRC_FILES := bar/bar.cpp
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/bar
include $(BUILD_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := native_activity
LOCAL_SRC_FILES := main.cpp

LOCAL_LDLIBS := -llog 
LOCAL_LDLIBS += -landroid 

LOCAL_SHARED_LIBRARIES := bar

LOCAL_STATIC_LIBRARIES += android_native_app_glue

include $(BUILD_SHARED_LIBRARY)
$(call import-module, android/native_app_glue)

私のネイティブ アクティビティのメイン クラスでは、次のようにライブラリをロードしようとしています。

void* lib = dlopen("/system/lib/armeabi-v7a/libbar.so", RTLD_NOW);
if (lib == NULL) {
    fprintf(stderr, "Could not dlopen(\"libbar.so\"): %s\n",
    dlerror());
    exit(1);
}else{
    LOGI("Library successfully loaded!");

    if (dlsym(lib, "bar") == NULL) {
        fprintf(stderr, "Symbol 'bar' is missing from shared library!!\n");        
    }else{
        LOGI("Library symbol found!"); 
    }

    int x = bar(25);
    LOGI("Bar return value: %i", x);
}

この実装の欠点は、JAVA メカニズムを使用して JNI の起動時にもこのライブラリをロードする必要があるため、実際にはランタイムのロードではないことです。

Bar ライブラリのプリコンパイル定義を Android.mk から削除すると、起動時の JNI ロードを無効にし、プリコンパイル済みライブラリのコピーをあるべきシステム/lib フォルダー (プリコンパイル定義を使用して格納されている場所と同じ場所) に追加します。ライブラリの失敗。期待どおり、lib フォルダーに手動でコピーしたライブラリが含まれている apk パッケージを確認しました。

なぜこれが機能しないのですか?外部のプリコンパイル済みライブラリの厳密なネイティブ ランタイム ライブラリの読み込みを実行することは可能ですか? また、私のライブラリが apk パッケージに確実に追加されるようにする最善の方法は何ですか?

4

1 に答える 1