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.

  • Creación de un archivo de encabezado para la clase de actividad de Android
  • Devuelve una matriz String en un método JNI
  • JNI: Llamar a GetStaticMethodID explotar
  • no se puede encontrar el símbolo "__android_log_write" - Registro nativo de Android
  • JNI y Gradle en Android Studio
  • Cómo llamar a un método Java desde C ++ / JNI que toma un parámetro de Contexto de Android
  • Compilación de Android JNI para OpenCV en Mac OSX
  • JNI manteniendo una referencia global a un objeto, accediendo a ella con otros métodos JNI. Mantener un objeto C ++ activo en varias llamadas JNI
  • Error de JNI: desbordamiento de tabla de referencia local 512 entradas
  • Tabla de referencia local de JNI de Android Expand
  • Android NDK R8E falta stdlib.h
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.