JNI-Wrapper beschweren sich über nicht definierte Referenzen

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

Ich versuche, die TagLib-Bibliothek in einer Android-App zu verwenden. Soweit ich weiß, muss ich dafür einen JNI-Wrapper schreiben. Ich wollte etwas Einfaches ausprobieren - lese den Titel aus dem Tag.

Ich habe den folgenden Code in Java geschrieben:

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 gab mir dann die Option, die Funktion automatisch in nativem Code zu generieren (die Datei heißt tagjni.c). Ich habe etwas von meinem eigenen Code hinzugefügt, um Funktionalität hinzuzufügen:

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

Mit der include-Anweisung läuft auch etwas. Ich kann #include schreiben und dann sagt das andere include, dass es unbenutzt ist. Wenn ich es lösche, wird keine der Variablen mehr erkannt. Wenn ich den Mauszeiger über die Fehler halte, erhalte ich die Option, #include hinzuzufügen.

Wenn ich versuche, die App auszuführen, erhalte ich den folgenden Fehler (und einige ähnliche): undefinierter Verweis auf 'taglib_set_strings_unicode'

Bedeutet das, dass die Funktion, die ich anrufe, nicht gefunden werden kann? Ich hatte eine Menge Probleme damit, die Bibliothek einzurichten und es irgendwie zum Laufen zu bringen. Als ich mit dem Schreiben des JNI-Wrappers begann, beschwerte sich Android Studio darüber, dass die .c-Datei nicht im Projekt enthalten ist. Nach dem Betrachten der NDK-Webseite dachte ich, dass ich eine Wurzel CMakeLists.txt erstellen und auf die anderen zwei (eine für TagLib und eine für JNI-Wrapper) verweisen muss. Ich weiß sehr wenig über C und CMakeLists. Das ist, was ich mir ausgedacht habe:

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 enthält bereits eine CMakeLists, also habe ich nur darauf hingewiesen. Für den JNI-Wrapper habe ich CMakeLists.txt in das Verzeichnis platziert, in dem der Code lautet:

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) 

Es scheint mir, dass ich hier etwas wirklich Offensichtliches vermisse. Ich glaube, es muss etwas mit der Art und Weise tun, wie ich CMake aufstelle, aber ich kann es nicht herausfinden.

No Answers Yet

Related questions

Hot questions

Language

Popular Tags