Cómo utilizar bibliotecas extra * .so en Android Studio y NDK

Estoy intentando generar una aplicación de Android para usar algunas bibliotecas extra * .so (específicamente 'libinterface.so'). Esas bibliotecas se generan externamente y se incluyen como una dependencia dentro de una clase de contenedor llamada desde Java. La biblioteca se almacena en 'src / main / jniLibs / armeabi-v7a'. El sistema incluye todo el archivo .so en la aplicación generada.

Anteriormente, estaba usando Eclipse para este propósito y pude usar esta biblioteca, pero tengo problemas para hacer esto con Android Studio.

El error generado es:

/home/******/Libraries/android-sdk-linux/ndk-bundle/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/aarch64-linux-android/4.9/../../../../aarch64-linux-android/bin/ld: cannot find -linterface 

Como el error es lanzado por el vinculador, parece relacionado con el paso de inclusión de biblioteca. En Eclipse, estaba usando un archivo 'Android.mk' para incluir la nueva biblioteca, pero no puedo encontrar la manera de hacerlo usando Gradle.

 #Android.mk LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := libinterface-prebuilt LOCAL_SRC_FILES := prebuilt/libinterface.so include $(PREBUILT_SHARED_LIBRARY) 

Estoy tratando de incluir las bibliotecas con esta definición gradle (Nota: He incluido el último soporte de JNI y gradle-experimental usando este tutorial ):

 ... android.buildTypes { release { minifyEnabled = false proguardFiles.add(file('proguard-android.txt')) } } android.ndk { moduleName = "custom_wrapper_jni" cppFlags.add("-I" + file("src/main/jni").absolutePath) cppFlags.add("-I" + file("../Integration/include").absolutePath) // <- New library header include path cppFlags.add("-L" + file("src/main/jniLibs/armeabi-v7a").absolutePath) // <- Path where the library is stored cppFlags.add("-std=c++11") stl = "stlport_static" // Which STL library to use: gnustl or stlport ldLibs.add("log") ldLibs.add("interface") //<- Library to be included } ... 

La biblioteca se compila externamente con las herramientas de CMake y makefile, y se compila de forma cruzada "correctamente" para la plataforma Android (probada con Eclipse y ADT).

He implementado la envoltura de esta manera:

 // custom_wrapper_jni.h #ifndef ANDROID_JNI_H #define ANDROID_JNI_H #include <jni.h> extern "C" { JNIEXPORT jint JNICALL Java_com_example_goe_android_JniInterface_testFunction(JNIEnv *env, jobject instance); } #endif 

y

 // custom_wrapper_jni.cpp #include <custom_wrapper_jni.h> #include "Interface.h" // Header of the included library Interface* mInterface = Interface::create(); // Generate the library class instance JNIEXPORT jint JNICALL Java_com_example_goe_android_JniInterface_testFunction(JNIEnv *env, jobject instance) { LOGI("Test function called in wrapper!"); return mInterface->test(); // Use the instance } 

El encabezado de la biblioteca se ve así:

 #ifndef INTERFACE_H__ #define INTERFACE_H__ #include <string> class Interface { public: static Interface* create(); virtual ~Interface(){} // Testing function virtual int test() = 0; protected: Interface(); }; #endif // INTERFACE_H__ 

Gracias por adelantado.

ACTUALIZAR:

Siguiendo este ejemplo , he incluido algunos bloques en el script gradle:

 def lib_path = file("src/main/jniLibs").absolutePath model { repositories { libs(PrebuiltLibraries) { newlibs { headers.srcDir file("../Integration/include").absolutePath binaries.withType(SharedLibraryBinary) { sharedLibraryFile = file("${lib_path}/${targetPlatform.getName()}/libinterface.so") println "Included libraries: " + file("${lib_path}/${targetPlatform.getName()}/libinterface.so") } } } } android { ... } android.sources { main { jni { dependencies { library "newlibs" linkage "shared" } } } } } 

Pero no funciona:

 Error: org.gradle.nativeplatform.toolchain.internal.CommandLineToolInvocationFailure: Linker failed while linking libcustom_wrapper_jni.so. 

Ok, podría haber dos problemas diferentes.

En primer lugar, debe asegurarse de que la biblioteca está compilada para la arquitectura correcta. Si está utilizando una biblioteca armeabi-v7a, pero el compilador está intentando cargar una biblioteca armeabi, la compilación fallará.

En segundo lugar, y siguiendo también con la primera edición, usted tiene que incluir las bibliotecas que dependen de la arquitectura usada. Utilice la configuración de ' sabores ' en su script build.gradle de módulo.

En el ejemplo, puede intentar hacer algo como esto:

 android.productFlavors { create("arm") { ndk.with{ abiFilters.add("armeabi") File curDir = file('./') curDir = file(curDir.absolutePath) String libsDir = curDir.absolutePath + "/src/main/jniLibs/armeabi/" ldLibs.add(libsDir + "libinterface.so") } } create("armv7") { ndk.with { abiFilters.add("armeabi-v7a") File curDir = file('./') curDir = file(curDir.absolutePath) String libsDir = curDir.absolutePath + "/src/main/jniLibs/armeabi-v7a/" ldLibs.add(libsDir + "libinterface.so") } } } 

Además, le sugiero que utilice 'jniLibs' para almacenar las librerías, ya que es la ruta predeterminada para ellas, pero utilice una carpeta diferente para cada arco.

Puedes consultar otros ejemplos como este .

Espero que esto ayude. Saludos.

  • ¿Cuál es la mejor manera de guardar JNIEnv *
  • JNI y Gradle en Android Studio
  • no se puede encontrar el símbolo "__android_log_write" - Registro nativo de Android
  • ¿Qué es "jobject this" en JNI y para qué se utiliza?
  • C El código JNI introduce errores en un proyecto Android Eclipse una vez que se abre el archivo C en el editor
  • ¿Cuáles son las consecuencias si intentamos conectar un hilo nativo permanentemente a la DVM (JVM)?
  • ¿Cómo arreglar el archivo libgnustl_shared.so duplicado que en sdks de terceros?
  • ¿Por qué no se está copiando libgnustl_shared.so desde mi APK?
  • Uso de Fluidsynth para reproducir notas de SoundFonts en Android
  • Cómo conectar una biblioteca C a la aplicación de iOS
  • Crear mapa de bits de la matriz de bytes, que se descomprime desde un archivo JPEG a través de libjpeg
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.