Envoltorio JNI quejándose de referencias indefinidas

Adrijan 07/27/2017. 0 answers, 39 views
android android c android-ndk android-ndk cmake jni

Intento usar la biblioteca TagLib en una aplicación de Android. Por lo que sé, tengo que escribir un contenedor JNI para eso. Quería probar algo simple: leer el título de la etiqueta.

Escribí el siguiente código en Java:

package developer.rogan.taglib;

import android.support.annotation.NonNull;
import android.util.Log;

public class TagJNI {

    private static final String TAG = "TagJNI";

    private String filename;
    private String title;

    public TagJNI(@NonNull String filename) {
        this.filename = filename;
    }

    public String getTitle() {
        Log.d(TAG, "getTitle, filename = " + filename);
        this.title = taglibGetTitle(filename);
        return title;
    }

    private native String taglibGetTitle(String filename);
} 

Android Studio me dio la opción de generar automáticamente la función en código nativo (el archivo se llama tagjni.c). Agregué un poco de mi propio código para agregar funcionalidad:

#include #include "../../../../../../Development/C++/taglib-1.11.1/bindings/c/tag_c.h"

TagLib_File *file;
TagLib_Tag *tag;
char *title;

JNIEXPORT jstring JNICALL
Java_developer_rogan_taglib_TagJNI_taglibGetTitle(JNIEnv *env, jobject instance,
                                                  jstring filename_) {

    taglib_set_strings_unicode(JNI_FALSE);
    const char *filename = (*env)->GetStringUTFChars(env, filename_, 0);

    file = taglib_file_new(filename);
    tag = taglib_file_tag(file);
    title = taglib_tag_title(tag);
    taglib_file_free(file);
    (*env)->ReleaseStringUTFChars(env, filename_, filename);
    return (*env)->NewStringUTF(env, title);
} 

También está sucediendo algo con la declaración de inclusión. Puedo escribir #include y luego el otro include dice que no se usa. Sin embargo, cuando lo elimino, ya no se reconoce ninguna de las variables. Cuando cierro los errores, tengo la opción de agregar el #include.

Cuando intento ejecutar la aplicación, aparece el siguiente error (y algunos más similares): referencia indefinida a 'taglib_set_strings_unicode'

¿Esto significa que no se puede encontrar la función que estoy llamando? Tuve muchos problemas al configurar la biblioteca y finalmente funcionó de alguna manera. Cuando empecé a escribir el contenedor JNI, Android Studio se quejó de que el archivo .c no se incluyera en el proyecto. Después de mirar la página web de NDK, pensé que tenía que crear una raíz CMakeLists.txt y hacer referencia a las otras dos (una para TagLib y otra para JNI). Sé muy poco sobre C y CMakeLists. Esto es lo que se me ocurrió:

cmake_minimum_required(VERSION 3.4.1)

add_subdirectory( # Specifies the directory of the CMakeLists.txt file.
                  /home/adrijan/Development/C++/taglib-1.11.1
                  # Specifies the directory for the build outputs.
                  /home/adrijan/devel/tagtest/taglib/src/main/cpp )
add_library( taglib SHARED IMPORTED )

add_subdirectory( # Specifies the directory of the CMakeLists.txt file.
                  /home/adrijan/devel/tagtest/taglib/src/main/jni
                  # Specifies the directory for the build outputs.
                  /home/adrijan/devel/tagtest/taglib ) 

TagLib ya incluye un CMakeLists, así que solo lo señalé. Para el contenedor JNI, coloque CMakeLists.txt dentro del directorio donde está el código:

cmake_minimum_required(VERSION 3.4.1)

# Specifies a library name, specifies whether the library is STATIC or
# SHARED, and provides relative paths to the source code. You can
# define multiple libraries by adding multiple add.library() commands,
# and CMake builds them for you. When you build your app, Gradle
# automatically packages shared libraries with your APK.

add_library( # Specifies the name of the library.
             jni-taglib

             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
             tagjni.c )

# Specifies a path to native header files.
include_directories(tagjni.h) 

Me parece que me falta algo realmente obvio aquí. Creo que tiene que hacer algo con la forma en que configuro CMake, pero no puedo resolverlo.

No Answers Yet

Related questions

Hot questions

Language

Popular Tags