Das NDK unterstützt mehrere C++-Laufzeitbibliotheken. Dieses Dokument enthält Informationen zu diesen Bibliotheken, den jeweiligen Vor- und Nachteilen und ihrer Verwendung.
C++-Laufzeitbibliotheken
Tabelle 1 NDK C++ Laufzeiten und Features.
Name | Funktionen |
---|---|
libc++ | Moderne C++-Unterstützung. |
system | new und delete . (in r18 eingestellt.) |
Keine | Keine Header, eingeschränkte C++. |
libc++ ist sowohl als statische als auch als gemeinsam genutzte Bibliothek verfügbar.
libc++
libc++ von LLVM ist der C++-Standard. Bibliothek, die seit Lollipop im Android-Betriebssystem und seit NDK r18 verwendet wird. ist die einzige im NDK verfügbare STL-Datei.
CMake verwendet standardmäßig die Version des C++ Clang, die standardmäßig verwendet wird (derzeit C++14),
Sie müssen also den standardmäßigen CMAKE_CXX_STANDARD
auf den entsprechenden Wert
in der Datei CMakeLists.txt
, um Funktionen in C++17 oder höher zu verwenden. CMake ansehen
Dokumentation für CMAKE_CXX_STANDARD
.
ndk-build lässt die Entscheidung auch standardmäßig über Clang, sodass ndk-build-Nutzer
sollte APP_CPPFLAGS
verwenden, um stattdessen -std=c++17
oder einen beliebigen anderen Ort hinzuzufügen.
Die gemeinsam genutzte Bibliothek für libc++ ist libc++_shared.so
und die statische Bibliothek
ist libc++_static.a
. In der Regel übernimmt das Build-System
und verpacken diese Bibliotheken
nach Bedarf für den Nutzer. Atypische Fälle
oder wenn Sie Ihr eigenes Build-System implementieren, lesen Sie den Artikel Build System Verwalter
Leitfaden oder die Anleitung zur Verwendung anderer Build-Systeme
Das LLVM-Projekt unterliegt der Apache-Lizenz v2.0 mit LLVM-Ausnahmen. Weitere Informationen finden Sie in der Lizenzdatei.
Infotainmentsystem
Die Systemlaufzeit bezieht sich auf /system/lib/libstdc++.so
. Diese Bibliothek sollte
mit dem voll funktionsfähigen libstdc++ von GNU verwechselt werden. Unter Android ist libstdc++ einfach
new
und delete
. Verwenden Sie libc++ für eine voll funktionsfähige C++-Standardbibliothek.
Die Systemlaufzeit von C++ bietet Unterstützung für die grundlegende C++-Laufzeit-ABI.
Im Wesentlichen stellt diese Bibliothek new
und delete
bereit. Im Gegensatz zu den anderen
Optionen im NDK verfügbar sind, wird die Ausnahmebehandlung oder
RTTI.
Abgesehen von den C++-Wrappern für das C++-Format wird keine Standardbibliothek unterstützt.
Bibliotheksheader wie <cstdio>
. Wenn Sie STL verwenden möchten, sollten Sie eine der
die anderen Optionen
auf dieser Seite.
Keine
Es gibt auch die Option, keine STL-Dateien zu verwenden. Es gibt keine Verknüpfungen oder Lizenzierungen Anforderungen erfüllt. Es sind keine C++-Standardheader verfügbar.
C++-Laufzeit auswählen
CMake
Der Standardwert für CMake ist c++_static
.
Sie können c++_shared
, c++_static
, none
oder system
mithilfe der
ANDROID_STL
in die Datei build.gradle
auf Modulebene ein. Weitere Informationen
finden Sie in der Dokumentation zu ANDROID_STL unter
CMake.
NK-Build
Der Standardwert für ndk-build ist none
.
Sie können c++_shared
, c++_static
, none
oder system
mithilfe der
APP_STL
in die Datei Application.mk ein. Beispiel:
APP_STL := c++_shared
Mit „ndk-build“ können Sie nur eine Laufzeit für Ihre App auswählen. Dies funktioniert nur in Application.mk aus.
Clang direkt verwenden
Wenn Sie Clang direkt in Ihrem eigenen Build-System verwenden, verwendet clang++
Standardmäßig c++_shared
. Wenn Sie die statische Variante verwenden möchten, fügen Sie -static-libstdc++
zu
Ihre Verknüpfungs-Flags. Beachten Sie, dass die Option zwar den Namen "libstdc++" für
aus historischen Gründen gilt, gilt dies auch für libc++.
Wichtige Hinweise
Statische Laufzeiten
Wenn der gesamte native Code Ihrer Anwendung in einem einzigen freigegebenen empfehlen wir die Verwendung der statischen Laufzeit. Dadurch kann die Verknüpfung und entfernen Sie möglichst viel ungenutzten Code. Dies führt zu einem optimierten und der kleinsten Anwendung. Außerdem werden PackageManager und dynamische Verknüpfungsfehler in alten Android-Versionen, die die Handhabung mehrerer gemeinsam genutzter schwierig und fehleranfällig.
In C++ ist es jedoch nicht sicher, mehr als eine Kopie derselben oder Objekt in einem einzelnen Programm verwenden. Dies ist ein Aspekt des Eine Definitionsregel, die im C++-Standard enthalten ist.
Wenn Sie eine statische Laufzeit (und statische Bibliotheken im Allgemeinen) verwenden, ist es einfach, gegen diese Regel verstoßen. Die folgende Anwendung unterbricht beispielsweise Regel:
# Application.mk
APP_STL := c++_static
# Android.mk
include $(CLEAR_VARS)
LOCAL_MODULE := foo
LOCAL_SRC_FILES := foo.cpp
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := bar
LOCAL_SRC_FILES := bar.cpp
LOCAL_SHARED_LIBRARIES := foo
include $(BUILD_SHARED_LIBRARY)
In dieser Situation hat die STL-Datei einschließlich der globalen Daten und statischen Konstruktoren in beiden Bibliotheken vorhanden ist. Das Laufzeitverhalten dieser Anwendung ist nicht definiert, und in der Praxis treten Abstürze sehr häufig auf. Andere mögliche Probleme umfassen:
- Arbeitsspeicher, der in einer Bibliothek zugewiesen und in der anderen freigegeben wurde, was zu Arbeitsspeicher führt oder Heap-Beschädigungen.
- In
libfoo.so
ausgelöste Ausnahmen, die inlibbar.so
nicht abgefangen werden, verursachen App abgestürzt. - Die Zwischenspeicherung von
std::cout
funktioniert nicht richtig.
Abgesehen von den damit verbundenen Verhaltensproblemen kann die Verknüpfung der statischen Laufzeit mit mehreren wird der Code in jeder gemeinsam genutzten Bibliothek dupliziert, wodurch die Größe der Ihre Anwendung.
Im Allgemeinen können Sie nur dann eine statische Variante der C++-Laufzeit verwenden, wenn Sie eine haben und nur eine gemeinsam genutzte Bibliothek in Ihrer Anwendung.
Freigegebene Laufzeiten
Wenn Ihre Anwendung mehrere gemeinsam genutzte Bibliotheken enthält, sollten Sie
libc++_shared.so
Unter Android ist die vom NDK verwendete libc++ nicht dieselbe wie die, die Teil der Datei ist.
des Betriebssystems. Dadurch erhalten NDK-Nutzer Zugriff auf die neuesten libc++-Funktionen und Fehler
auch bei älteren Android-Versionen behoben werden. Wenn Sie jedoch
libc++_shared.so
verwenden, müssen Sie es in Ihre App aufnehmen. Wenn Sie Ihre eigene
Mit Gradle erfolgt dies automatisch.
Bei alten Android-Versionen traten Fehler im PackageManager und im Dynamic Linker auf
führten dazu, dass die Installation, Aktualisierung und das Laden nativer Bibliotheken
unzuverlässig werden. Wenn Ihre App auf eine frühere Android-Version
als Android 4.3 (Android API-Level 18) und Sie libc++_shared.so
verwenden,
muss die gemeinsam genutzte Bibliothek vor jeder anderen davon abhängigen Bibliothek geladen werden.
Das Projekt ReLinker bietet Behelfslösungen für alle bekannten Probleme beim Laden nativer Bibliotheken. eine bessere Wahl, als eigene Behelfslösungen zu schreiben.
Eine STL pro App
In der Vergangenheit unterstützte das NDK neben libc++ auch GNU libstdc++ und STLport. Wenn Ihre Anwendung von vordefinierten Bibliotheken abhängt, die für ein NDK erstellt wurden als die, mit der Ihre App erstellt wurde, müssen Sie sicherstellen, dass dies auf kompatible Weise geschieht.
Eine Anwendung sollte nicht mehr als eine C++-Laufzeit verwenden. Die verschiedenen STLs sind
nicht miteinander kompatibel. Beispiel: Das Layout von std::string
in libc++ ist nicht dasselbe wie in gnustl. Bei Code, der für ein STL geschrieben wird,
keine Objekte verwenden können, die gegen ein anderes geschrieben wurden. Dies ist nur ein Beispiel:
Es gibt zahlreiche Inkompatibilitäten.
Diese Regel geht über Ihren Code hinaus. Alle Abhängigkeiten müssen die gleiche die ausgewählte STL-Datei. Wenn Sie von einem Closed-Source-Drittanbieter abhängig sind die STL verwendet und keine Bibliothek pro STL zur Verfügung stellt, haben die Wahl in STL. Sie müssen dieselbe STL-Datei wie Ihre Abhängigkeit verwenden.
Es ist möglich, dass Sie von zwei sich gegenseitig inkompatiblen Bibliotheken abhängig sind. In In dieser Situation besteht die einzige Lösung darin, eine der Abhängigkeiten zu entfernen oder für die Bereitstellung einer Bibliothek, die parallel zur anderen STL-Datei erstellt wurde.
C++ Ausnahmen
C++-Ausnahmen werden von libc++ unterstützt, sind aber in „ndk-build“. Das liegt daran, dass in der Vergangenheit keine C++-Ausnahmen in der NDK Für CMake- und eigenständige Toolchains sind C++-Ausnahmen standardmäßig aktiviert.
Um Ausnahmen für Ihre gesamte Anwendung in "ndk-build" zu aktivieren, fügen Sie den Parameter folgende Zeile in die Datei Application.mk ein:
APP_CPPFLAGS := -fexceptions
Um Ausnahmen für ein einzelnes ndk-build-Modul zu aktivieren, fügen Sie folgende Zeile zu Modul in seiner Android.mk-Datei:
LOCAL_CPP_FEATURES := exceptions
Alternativ können Sie auch Folgendes verwenden:
LOCAL_CPPFLAGS := -fexceptions
RTTI
Wie mit Ausnahmen wird RTTI von libc++ unterstützt, ist aber in „ndk-build“. Für CMake- und eigenständige Toolchains ist RTTI standardmäßig aktiviert.
Um RTTI in Ihrer gesamten Anwendung in ndk-build zu aktivieren, fügen Sie Folgendes hinzu: in die Datei Application.mk ein:
APP_CPPFLAGS := -frtti
Um RTTI für ein einzelnes ndk-build-Modul zu aktivieren, fügen Sie die folgende Zeile zur Modul in seiner Android.mk-Datei enthält:
LOCAL_CPP_FEATURES := rtti
Alternativ können Sie auch Folgendes verwenden:
LOCAL_CPPFLAGS := -frtti