L'encapsuleur JNI se plaint de références indéfinies

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

J'essaie d'utiliser la bibliothèque TagLib dans une application Android. Pour autant que je sache, je dois écrire un wrapper JNI pour cela. Je voulais essayer quelque chose de simple - lire le titre de l'étiquette.

J'ai écrit le code suivant 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 m'a alors donné la possibilité de générer automatiquement la fonction en code natif (le fichier s'appelle tagjni.c). J'ai ajouté un peu de mon propre code pour ajouter des fonctionnalités:

#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);
} 

Il y a quelque chose qui se passe avec l'instruction include aussi. Je peux écrire #include et l'autre dit dit que c'est inutilisé. Cependant, quand je le supprime, aucune des variables n'est plus reconnue. Lorsque je survole les erreurs, j'ai l'option d'ajouter le #include.

Lorsque j'essaie d'exécuter l'application, j'obtiens l'erreur suivante (et d'autres plus similaires): référence non définie à 'taglib_set_strings_unicode'

Cela signifie-t-il que la fonction que j'appelle ne peut pas être trouvée? J'ai eu beaucoup de problèmes à mettre la bibliothèque en place et finalement je l'ai fait fonctionner d'une manière ou d'une autre. Lorsque j'ai commencé à écrire l'encapsuleur JNI, Android Studio s'est plaint que le fichier .c n'était pas inclus dans le projet. Après avoir regardé la page Web de NDK, j'ai pensé que je devais créer une racine CMakeLists.txt et faire référence aux deux autres (une pour TagLib et une pour l'enveloppe JNI). Je connais très peu de choses sur C et CMakeLists. C'est ce que j'ai trouvé:

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 inclut déjà un CMakeLists ainsi je l'ai juste indiqué. Pour le wrapper JNI, j'ai placé CMakeLists.txt dans le répertoire où le code est:

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) 

Il me semble qu'il me manque quelque chose de vraiment évident ici. Je crois qu'il doit faire quelque chose avec la façon dont j'ai mis en place CMake, mais je ne peux pas le comprendre.

No Answers Yet

Related questions

Hot questions

Language

Popular Tags