web-dev-qa-db-fra.com

Utiliser C++ avec Android ndk/jni

Tous les exemples ndk utilisent uniquement les 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 rappel jni, tout fonctionne correctement.

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 importante de Java, mais elle appellera du code C natif pour les calculs gourmands en ressources CPU (déjà écrit en C++, avec des classes et d’autres éléments C++).

Voici mon monde de salut comme strcuture 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 ça ne compile pas. Tourner second.cpp dans un fichier .c soulève une erreur lors de l’inclusion du fichier d’en-tête, je suppose que c’est parce qu’il ne s’agit pas d’un fichier C++.

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

Le rendre .cpp soulève 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.

Avez-vous une idée de comment compiler cette chose?

Merci

34
user745189

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

De Android-MK.html :

Notez que l'extension par défaut pour les fichiers source C++ est '.cpp'. Il est Cependant, il est possible d'en spécifier un autre en définissant la variable LOCAL_CPP_EXTENSION. N'oubliez pas le point initial (par exemple, ".cxx" fonctionnera, mais pas "cxx").

15
Michael

Vous devrez recompiler toutes les bibliothèques natives spécifiquement pour Android. Vous avez besoin du code source pour toutes les bibliothèques natives tierces que vous prévoyez d’utiliser, car généralement, lorsque nous compilons et lions ces bibliothèques en dehors d’Android, elles sont liées à glibc, mais malheureusement, Android n’utilise pas glibc en raison de problèmes de performance et de manque. Android utilise une version diluée de glibc appelée libc. Il a des noms de symbole correspondants à la glibc pour la plupart des fonctionnalités habituelles. Mais pour autant que je sache, la libc ne dispose pas de certaines fonctionnalités liées à strings et elle n’a certainement pas de support posix. Si vos bibliothèques natives utilisent l'une des fonctionnalités obsolètes, vous devrez trouver une solution de contournement en utilisant une fonctionnalité alternative prise en charge par libc et en codant vos bibliothèques en conséquence. 

En outre, comme vous l'avez bien fait remarquer, vous devrez utiliser le NDK pour interfacer Java (Android app/fwk) avec le monde natif (C++). 

Bien que cela semble assez simple, la compilation de bibliothèques natives sur Android (portage Android) prend généralement beaucoup de temps, sans garantie de succès.

3
Alok Save

À propos de votre erreur de compilation, vous avez tout d'abord appelé "second.c" puis renommé "second.cpp", mais les fichiers objet ont toujours le nom "second.c", donc avant de compiler (bdk-build) vous devez supprimer les fichiers * .o et * .d dans/cygdrive/c/Android-ndk-r5c/samples/two-libs/obj/local/armeabi/objs/twolib-second /

1
Bush

erreur: attendu '=', ',', ';', ',' asm 'ou' __ attribut __ 'avant' classe '

Cas classique de manquant ';' avant le mot-clé de classe? Imaginer

 int functionname(int p)
 class X { } ;

Cela pourrait conduire à votre message du compilateur assez facilement. Un facteur de complication commun est quand il ressemble réellement à

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

et l'erreur est dans la dernière déclaration dans someheader.h/ou tout fichier inclus récursivement /;)

0
sehe

Courir:

ndk-build clean

après avoir modifié un Android.mk incorrect, sinon la génération peut continuer à échouer même si vous avez corrigé la configuration.

Je pense que c'est ce que le PO voulait dire sur ce commentaire .

Modifier Android.mk

Modifiez les instances de LOCAL_SRC_FILES et supprimez le ./ du début de chaque ligne.

0