Android NDK / JNI – referencia indefinida a la función definida en el archivo de encabezado personalizado

Utilizando JNI, estoy tratando de escribir un método C ++ nativo para el Android NDK que hace una llamada a una función C definida en un archivo de encabezado personalizado. Sin embargo, estoy recibiendo un error de referencia indefinido para mi llamada de función C.

Aquí está mi código C ++ que hace una llamada a la función C y devuelve su resultado a Java como jstring:

#include <jni.h> #include "gesture_detector.h" JNIEXPORT jstring JNICALL Java_com_example_bmtitest_JavaAbstractionLayer_callGestureAnalysis(JNIEnv *env, jobject obj, jfloat previousX, jfloat previousY, jfloat currentX, jfloat currentY) { return env->NewStringUTF(gestureAnalysis(previousX, previousY, currentX, currentY)); } 

Aquí está mi función C:

 #include <stdio.h> #include "gesture_detector.h" //implemented from gesture_detector.h const char* gestureAnalysis(float previousX, float previousY, float currentX, float currentY) { float xOffset = currentX - previousX; float yOffset = currentY - previousY; if(xOffset == 0 && yOffset == 0) { return "TAP"; } return "0"; } 

Aquí está mi código de Android.mk:

 LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := gestureDetector LOCAL_SRC_FILES := gestureDetector.c NativeAbstractionLayer.cpp LOCAL_LDLIBS := -landroid include $(BUILD_SHARED_LIBRARY) 

Aparentemente, parece que no se encuentra la definición de función definida en el archivo de encabezado personalizado ( gesture_detector.h ). Creo que puede ser un problema en mi archivo Android.mk.

¿Podría alguien decirme qué estoy haciendo mal aquí?

Un error de "referencia indefinida" proviene del enlazador . Su archivo de encabezado sólo satisfizo al compilador.

Sin embargo, ya que usted está mezclando C y C + + su problema es probable mangling . Básicamente, usted necesita decirle al compilador C ++ que la función que está tratando de llamar fue creada por un compilador C en lugar de un C ++, y por lo tanto no tiene códigos de tipo de argumento injertados en su nombre. En este momento no sabe que, por lo que está tratando de llamar a la función por un estilo C ++ decorado nombre que difiere de la simple C nombre de la función que el enlazador en realidad tiene disponible.

Agregue esto al principio de su archivo gesture_detector.h:

 #ifdef __cplusplus extern "C" { #endif 

Y esto al final

 #ifdef __cplusplus } #endif 

Y hacer una reconstrucción limpia.

Si su verdadera lógica jni cola es tan trivial como la versión presentada aquí, cambiar a una versión C de que también podría ser una opción – pero tenga en cuenta que la sintaxis jni es diferente en C y C + +, por lo que no puede cambiar la extensión de archivo .

Simplemente haciendo su código C ++ nativo entre

 extern "C" { your code } 

Es algo que no necesariamente funcionará necesariamente – como puede comprobar aquí .

Prueba a agregar al archivo Android.mk:

 LOCAL_ALLOW_UNDEFINED_SYMBOLS := true 

Aquí encontrará más información al respecto.

  • Android NDK Exception failed: dlopen failed: no se puede localizar el símbolo "_ZN7Tangram11setPositionEdd" referenciado por "libtangram.so"
  • Es una pérdida de una sola vez de referencia a la memoria nativa asignada por una aplicación Android un gran negocio?
  • Creación de un android.graphics.Bitmap desde C ++
  • ¿Cómo maneja la superficie la recolección de basura después de ser parcelada en Android?
  • Uso de minizip con android ndk
  • Cómo depurar SEGV_ACCERR
  • Pasar el puntero de C a Java se convierte en NULL
  • Jni Tutorial para android
  • Error de UnsatisfiedLink: Método nativo no encontrado findLibrary devuelto null
  • Android: error al cargar la biblioteca
  • Utilizar una clase simple de C ++ en Android NDK
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.