Android NDK: crea dos bibliotecas compartidas nativas que se llaman

Desperdiciado medio día tratando de construir dos bibliotecas compartidas, por ejemplo, mod1 y mod2 (que Android NDK compila libmod1.so y libmod2.so ), de fuentes en una carpeta jni y subcarpetas, entonces mod1 llamar a una función de mod2. Un montón de respuestas sobre cómo hacer que el trabajo de construcción, pero luego el enlace dinámico de ejecución no estaba funcionando, la aplicación se estrelló en el arranque.

Decidió publicar esta pregunta y responderla inmediatamente, de modo que Q y A de todo el proceso estén juntos, y espero que alguien más no pierda un día investigándolo de nuevo.

El procedimiento de compilación correcto era relativamente fácil, mi problema era que hacer que libmod1.so dependiera de libmod2.so causaba enlaces insatisfechos al iniciar – el código mod1 no podía encontrar la biblioteca compartida mod2, aunque ambos estaban presentes dentro de la misma carpeta en el APK final, bajo libs / armeabi, libs / x86 etc. Sin embargo, para hacer mi respuesta completa:

  • Coloque sus fuentes de C o C ++ y los archivos de encabezado en subdirectorios de dir jni en su proyecto de Android, por ejemplo carpetas mod1 / y mod2 /

  • Por instrucciones de NDK, cree el archivo de Application.mk, eg el mío es:

NDK_TOOLCHAIN_VERSION = 4.7
APP_PLATFORM: = android-8
APP_ABI: = armeabi armeabi-v7a x86

  • Crea Android.mk siguiendo esta plantilla:

LOCAL_PATH: = $ (llame a my-dir)
incluya $ (CLEAR_VARS)
LOCAL_SHARED_LIBRARIES: = mod2 # esto hace que libmod1.so dependa de libmod2.so
LOCAL_MODULE: = mod1
LOCAL_SRC_FILES: = mod1 / file1.c
LOCAL_SRC_FILES + = mod1 / file2.cpp

incluya $ (BUILD_SHARED_LIBRARY) # esto construye realmente libmod1.so

incluya $ (CLEAR_VARS)
LOCAL_MODULE: = mod2
LOCAL_SRC_FILES: = mod2 / file1.cc
LOCAL_SRC_FILES + = mod2 / file2.cc

incluyen $ (BUILD_SHARED_LIBRARY) # esto construye libmod2.so

Eso es todo, todas las compilaciones sin quejas con script ndkbuild. Sólo necesita un contenedor C para llamar a algunas funciones de Java. Y aquí estaba mi problema. Desde que tenía las funciones Callable de Java sólo en libmod1.so, mi clase C contenedor en Java era como:

 public class CWrapper { static { System.loadLibrary("mod1"); } public static native int func1(String aParam); ... } 

Esto me pareció perfectamente lógico: llamo a libmod1.so desde Java, así que utilicé System.loadLibrary ("mod1"), y puesto que libmod1.so sabe que depende de libmod2.so, y ambos archivos están en la misma carpeta, libmod1 sabrá cómo encontrar y cargar libmod2, ¿verdad? ¡Incorrecto! Se estaba estrellando en el inicio de la aplicación con "enlace insatisfecho". El mensaje de error exacto fue:

 java.lang.UnsatisfiedLinkError: Cannot load library: soinfo_link_image(linker.cpp:1635): could not load library "libmod2.so" needed by "libmod1.so"; caused by load_library(linker.cpp:745): library "libmod2.so" not found 

Buscaba en todas partes un código más para agregar a Android.mk para resolver esto en vano. ¡Finalmente Eureka! Modifiqué mi clase CWrapper de la siguiente manera:

 public class CWrapper { static { System.loadLibrary("mod2"); // must be first, as mod1 depends on mod2! System.loadLibrary("mod1"); } public static native int func1(String aParam); ... } 

y las cosas empezaron a funcionar como un encanto …

Greg

  • Android JNI: GetObjectClass se bloquea con SIGSEGV (no es una referencia JNI válida)
  • JNI cambiar C a C ++
  • Cómo agregar un servicio de sistema a Android Framework
  • Jni Tutorial para android
  • ¿Cómo realizar llamadas JNI desde un servicio incluso si la aplicación está cerrada?
  • Cómo depurar una aplicación en Android con GDBSERVER?
  • Jni llama al método java que toma una interfaz java personalizada como parámetro
  • Obtener un ANativeWindowBuffer de ANativeWindow_Buffer
  • Obtener un puntero JNIEnv válido
  • Cómo depurar SEGV_ACCERR
  • Detección de fugas de memoria nativas en el código JNI de Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.