34 votes

Utiliser C++ avec Android ndk/jni

Tous les échantillons ndk n'utilisent que des fonctions C de base déclarées comme extern dans l'en-tête et définies dans le fichier cpp. Ensuite, après avoir inclus le fichier d'en-tête dans le fichier C contenant le callback jni, tout fonctionne bien.

Est-il possible d'utiliser des classes C++ avec le ndk Android ? Mon application ne sera pas une activité native, elle aura toujours une partie java importante mais elle fera appel à du code C natif pour les calculs intensifs du CPU (déjà écrit en C++, avec des classes et autres trucs C++).

Voici ma strcuture de type hello-world pour le moment :

Fichier "first.h"

#ifndef FIRST_H
#define FIRST_H

class Test
{};

#endif /* FIRST_H */

Fichier "second.cpp"

#include <jni.h>
#include "first.h"

#ifdef __cplusplus
extern "C" {
#endif

jint Java_com_example_twolibs_TwoLibs_add( JNIEnv*  env,
                                      jobject  this,
                                      jint     x,
                                      jint     y )
{
    Test t;
    return 0;
}

#ifdef __cplusplus
}
#endif

Et enfin Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := libtwolib-second
LOCAL_SRC_FILES := second.cpp

include $(BUILD_SHARED_LIBRARY)

Assez basique mais qui ne se compile pas. Transformer second.cpp en fichier .c soulève une erreur lors de l'inclusion du fichier d'en-tête, je suppose que c'est parce que ce n'est pas un fichier C++.

error: expected '=', ',', ';', 'asm' or '__attribute__' before 'Test'

En le transformant en .cpp, on obtient l'erreur suivante :

make: *** No rule to make target `/cygdrive/c/android-ndk-r5c/samples/twolibs/jni/second.c', needed by `/cygdrive/c/android-ndk-r5c/samples/two-libs/obj/local/armeabi/objs/twolib-second/second.o'.  Stop.

Une idée de comment je peux faire compiler ce truc ?

Merci

15voto

Michael Points 16659

Vous pouvez utiliser C++ avec NDK, mais les fichiers contenant du code C++ doivent avoir l'extension .cpp.

De Android-MK.html :

Notez que l'extension par défaut des fichiers source C++ est '.cpp'. Il est toutefois possible d'en spécifier une autre en définissant la variable LOCAL_CPP_EXTENSION. N'oubliez pas le point initial (c'est à dire que '.cxx' sera utilisé comme extension de fichier). fonctionnera, mais pas 'cxx').

3voto

Alok Save Points 115848

Vous devrez recompiler toutes les bibliothèques natives spécifiquement pour Android. Vous aurez besoin du code source de toutes les librairies natives tierces que vous prévoyez d'utiliser, simplement parce qu'en général, lorsque nous compilons et lions ces librairies en dehors d'Android, elles sont liées à glibc mais malheureusement Android n'utilise pas glibc en raison de problèmes de licence et de performance. Android utilise une version édulcorée de glibc appelé libc . Elle a des noms de symboles correspondants à ceux de la glibc pour la plupart des fonctionnalités habituelles. Mais pour autant que je sache, la libc n'a pas certaines fonctionnalités liées à la glibc. strings et elle n'en a certainement pas posix soutien. Si vos bibliothèques natives utilisent l'une des fonctionnalités dépréciées, vous devrez trouver une solution de contournement en utilisant des fonctionnalités alternatives prises en charge par le programme libc et de coder vos librairies en conséquence.

De plus, comme vous l'avez souligné à juste titre, vous devrez utiliser le NDK pour interfacer Java (application Android/fwk) avec le monde natif (C++).

Bien que cela semble assez simple, d'après mon expérience, la compilation de bibliothèques natives sur Android (portage Android) a traditionnellement pris beaucoup de temps sans garantie de succès.

1voto

Bush Points 593

A propos de votre erreur de compilation, il semble que vous l'ayez d'abord appelé "second.c" puis renommé en "second.cpp" mais les fichiers objets ont toujours le nom "second.c", donc avant de compiler (bdk-build) vous devez supprimer les fichiers *.o et *.d dans le répertoire /cygdrive/c/Android-ndk-r5c/samples/two-libs/obj/local/armeabi/objs/twolib-second/.

0voto

sehe Points 123151

erreur : on s'attendait à ce que '=', ',', ';', 'asm' ou '__ attribut __' précède 'class'.

Un cas classique d'omission de " ;" devant le mot-clé "classe" ? Imaginez

 int functionname(int p)
 class X { } ;

Cela pourrait conduire à votre message du compilateur assez facilement. Un facteur de complication commun est quand cela ressemble à

 #include "someheader.h"
 class X { } ;

et l'erreur se trouve dans la dernière déclaration à l'intérieur de someheader.h /ou tout autre fichier inclus récursivement/ ;)

0voto

Ciro Santilli Points 3341

Cours :

ndk-build clean

après avoir modifié une erreur Android.mk sinon la construction peut continuer à échouer même si vous avez corrigé la configuration.

Je pense que c'est ce que l'OP voulait dire sur ce commentaire .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X