webentwicklung-frage-antwort-db.com.de

Verwenden Sie C++ mit Android ndk/jni

Alle ndk-Beispiele verwenden nur grundlegende C-Funktionen, die im Header als extern deklariert und in der cpp-Datei definiert sind. Nach dem Einfügen der Header-Datei in die C-Datei mit dem jni-Callback funktioniert alles einwandfrei.

Ist es möglich, C++ - Klassen mit der Android-ndk zu verwenden? Meine Anwendung wird keine native Aktivität sein, sie hat immer noch einen wichtigen Java-Teil, ruft jedoch nativen C-Code für die CPU-intensive Berechnung auf (bereits in C++ geschrieben, mit Klassen und anderen C++ - Elementen).

Hier ist meine Hallo-Welt fürs Erste:

Datei "first.h"

#ifndef FIRST_H
#define FIRST_H

class Test
{};

#endif /* FIRST_H */

Datei "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

Und schließlich Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

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

include $(BUILD_SHARED_LIBRARY)

Ziemlich einfach, aber das kompiliert nicht. Wenn Sie second.cpp in eine .c-Datei umwandeln, wird beim Einfügen der Header-Datei ein Fehler ausgegeben.

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

Bei der Erstellung einer .cpp-Datei wird der folgende Fehler angezeigt:

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.

Irgendeine Idee, wie ich das Ding kompilieren kann?

Vielen Dank

34
user745189

Sie können C++ mit NDK verwenden, aber Dateien mit C++ - Code müssen die Erweiterung .cpp haben.

Von Android-MK.html :

Beachten Sie, dass die Standarderweiterung für C++ - Quelldateien ".cpp" ist. Es ist Es ist jedoch möglich, eine andere zu definieren, indem die Variable definiert wird LOCAL_CPP_EXTENSION. Vergiss nicht den Anfangspunkt (d. H. '.Cxx' wird funktionieren, aber nicht 'cxx').

15
Michael

Sie müssen alle nativen Bibliotheken speziell für Android neu kompilieren. Sie benötigen den Quellcode für alle nativen Drittanbieter-Bibliotheken, die Sie verwenden möchten, weil die Bibliotheken normalerweise außerhalb von Android kompiliert und mit glibc verknüpft sind. Leider verwendet Android glibc aus Liscenz- und Leistungsproblemen nicht. Android verwendet eine verwässerte Version von glibc mit dem Namen libc. Es hat übereinstimmende Symbolnamen für die meisten der üblichen Funktionen zu glibc. Soweit ich weiß, hat die libc keine mit strings zusammenhängende Funktionalität und definitiv keine posix-Unterstützung. Wenn Ihre nativen Bibliotheken eine der veralteten Funktionen verwenden, müssen Sie eine Problemumgehung finden, indem Sie die von libc unterstützten alternativen Funktionen verwenden und Ihre Bibliotheken entsprechend codieren. 

Wie Sie ganz klar gesagt haben, müssen Sie das NDK verwenden, um Java (Android-App/fwk) mit der nativen Welt (C++) zu verbinden. 

Obwohl dies nach meiner Erfahrung ziemlich einfach klingt, native Bibliotheken auf Android (Android-Portierung) zusammenzustellen, ist es traditionell sehr zeitaufwändig, ohne dass es Erfolge gibt.

3
Alok Save

Ihr Kompilierungsfehler scheint, als hätten Sie sie zuerst "second.c" genannt und später in "second.cpp" umbenannt, aber die Objektdateien haben immer noch den Namen "second.c", bevor Sie sie kompilieren Sie müssen die Dateien * .o und * .d im Verzeichnis/cygdrive/c/Android-ndk-r5c/samples/two-libs/obj/local/armeabi/objs/twolib-second/entfernen

1
Bush

fehler: erwartet '=', ',', ';', 'asm' oder '__ Attribut __' vor 'Klasse'

Klassischer Fall von fehlenden ';' vor dem Klassenschlüsselwort? Vorstellen

 int functionname(int p)
 class X { } ;

Dies kann leicht zu einer Compiler-Nachricht führen. Ein häufiger komplizierender Faktor ist, wenn es tatsächlich so aussieht

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

und der Fehler ist in der letzten Deklaration in someheader.h/oder in einer rekursiv eingeschlossenen Datei /;) enthalten.

0
sehe

Lauf:

ndk-build clean

nachdem Sie einen falschen Android.mk geändert haben, schlägt der Build möglicherweise fehl, selbst wenn Sie die Konfiguration korrigiert haben.

Ich denke, das war es, was das OP bedeutete zu diesem Kommentar .

Bearbeiten Sie Android.mk

Ändern Sie die Instanzen von LOCAL_SRC_FILES und entfernen Sie die ./ aus dem Anfang jeder Zeile.