web-dev-qa-db-fra.com

Importer une bibliothèque c ++ existante (fichier .a ou .so) ndk android

Je viens de passer par le développement natif sur Android. Je réussis à obtenir mon AndroidStudio 2.2.2 prêt pour le développement natif

Je construis également un exemple hello-jni project

Ce que j'essaie de réaliser

J'essaie d'utiliser une bibliothèque existante conçue en c ++ (une bibliothèque statique .a extension ou .so fichier me sera fournie)

Peu de confusions concernant le développement autochtone

1) Dois-je utiliser les fichiers .cpp & .h de la bibliothèque c ++ existante au lieu de .a ou .so fichier?

2) Dois-je créer CMakeLists.text : Pour autant que je googe mes fichiers .a n'est pas généré à l'aide de ndk-build , je dois donc le créer.

Si j'utilise les fichiers .cpp & .h , dois-je créer Android.mk & Application.mk

Est-ce que CMakeLists.text compile mon projet Android nouvellement développé en tant que bibliothèque ou mon fichier .a existant?

3) Où est-ce que je place le fichier .a dans mon projet? Est-ce dans le dossier jni?

4) Les fichiers de classe Java doivent-ils définir les méthodes avec mot clé native identique à celui implémenté dans un fichier c ++ (Exemple: nom de la méthode de fichier c ++ getData (), la classe Java doit-elle contenir la méthode native native getData ())

10
karthik kolanji

Ok, donc vous avez un tas de questions. Certaines de ces questions sont de type préférence personnelle, mais je les fournirai comme choix personnel. 

1

Ceci est votre choix. Personnellement, j'utiliserais le fichier .so compilé. De cette façon, je n'ai jamais à m'inquiéter des fichiers NDK, CMake et .mk. Si vous avez le fichier, il vous suffit de l'ajouter au dossier libs (pas le dossier lib) et de modifier légèrement votre fichier build.gradle. C'est tout.

Changer en build.gradle:

sourceSets {
    main {
        manifest.srcFile 'AndroidManifest.xml'
        Java.srcDirs = ['src']
        res.srcDirs = ['res']
        assets.srcDirs = ['assets']
        jniLibs.srcDirs = ['libs']
    }
}

2 et 3

Celles-ci ne seraient pas pertinentes avec cette option.

4

Peu importe que vous utilisiez les fichiers ou les bibliothèques compilées:

@SuppressWarnings("JniMissingFunction")
public class MyNativeMethods {
    static {
        System.loadLibrary("my_native_lib");
    }

    public native int native_method_1(int fd);
    public native int native_method_2(int fd);
    public native void native_method_3(int fd, int arr[]);
    public native int[] native_method_4(int fd);
}

Et ensuite, vous pouvez appeler ces méthodes à partir de votre ActivityFragment.

J'espère que c'est assez clair.

_/EDIT (basé sur le commentaire ci-dessous):

1) Les fichiers .so ou .a sont vos bibliothèques natives. 

2) Les fichiers .cpp, .c, etc. ne sont que vos fichiers de code source natif. Si vous deviez utiliser ces fichiers dans le projet, vous devriez utiliser un système de construction (par exemple, CMake) pour les utiliser. CMake prend vos fichiers de code source et crée une bibliothèque .so qui est à nouveau la bibliothèque native. C'est pourquoi j'ai suggéré d'utiliser les fichiers .so, car pourquoi implémenter CMake dans votre projet alors que vous n'en avez pas besoin?

Si tu veux essayer CMake ou l'apprendre à l'avenir, vérifie cette réponse: C/C++ avec Android Studio version 2.2

3) System.loadLibrary("my_native_lib");: Ici, vous indiquez au runtime Java d’ajouter cette bibliothèque. De cette façon, vous créez un lien entre Java et le code C++ qui se trouve dans la bibliothèque. Les méthodes situées sous cette ligne doivent avoir le même nom que dans le code C++/C. De cette manière, le moteur d’exécution Java trouvera et ouvrira la bibliothèque et recherchera ces méthodes dans la bibliothèque que vous chargez. Voir plus ici

14

De ici

Ouverture de bibliothèques partagées directement à partir d'un APK

À partir du niveau d’API 23 et supérieur, il est possible d’ouvrir un fichier .so directement à partir de votre APK. Utilisez simplement System.loadLibrary ("foo") exactement comme d'habitude, mais définissez Android: extractNativeLibs = "false" dans votre fichier AndroidManifest.xml. Dans les versions antérieures, les fichiers .so étaient extraits du fichier APK au moment de l'installation. Cela signifiait qu'ils occupaient de l'espace dans votre fichier APK et dans votre répertoire d'installation (et cela a été compté pour vous et signalé à l'utilisateur comme un espace occupé par votre application). Tout fichier .so que vous souhaitez charger directement à partir de votre APK doit être aligné sur la page (sur une limite de 4096 octets) dans le fichier Zip et stocké non compressé. Les versions actuelles de l'outil zipalign prennent en charge l'alignement.

Notez que dans les API de niveau 23 et supérieur, dlopen (3) ouvrira une bibliothèque à partir de n’importe quel fichier Zip, pas seulement de votre APK. Il suffit de donner à dlopen (3) un chemin sous la forme "my_Zip_file.Zip! /Libs/libstuff.so". Comme pour les fichiers APK, la bibliothèque doit être alignée sur une page et stockée non compressée pour que cela fonctionne.

1
not2qubit
0
CLIFFORD P Y