Android ndk std:: pour la chaîne de soutien
j'utilise android NDK r9d et chaîne d'outils 4.8 mais je ne suis pas en mesure d'utiliser la fonction std::to_string, compilateur jette cette erreur:
error: 'to_string' is not a member of 'std'
cette fonction n'est-elle pas prise en charge sur android ndk? J'ai essayé APP_CPPFLAGS := -std=c++11
sans succès.
6 réponses
Vous pouvez essayer LOCAL_CFLAGS := -std=c++11
, mais note que ne sont pas tous C++11 Api sont disponibles avec le NDK est gnustl . Le support C++14 complet est disponible avec libc++ ( APP_STL := c++_shared
).
l'alternative est de l'implémenter vous-même.
#include <string>
#include <sstream>
template <typename T>
std::string to_string(T value)
{
std::ostringstream os ;
os << value ;
return os.str() ;
}
int main()
{
std::string perfect = to_string(5) ;
}
avec NDK r9+ vous pouvez utiliser llvm-libc++ qui offre un support complet pour cpp11.
dans votre Application .mk vous devez ajouter:
APP_STL:=c++_static
ou
APP_STL:=c++_shared
Gradle
si vous cherchez une solution pour le système de construction Gradle. Regardez cette réponse .
courte réponse.
ajouter la chaîne
arguments "-DANDROID_STL=c++_shared"
dans votre build.gradle
. Comme
android {
...
defaultConfig {
...
externalNativeBuild {
cmake {
...
arguments "-DANDROID_STL=c++_shared"
}
}
}
...
}
Expérimental Plugin Gradle
si vous cherchez une solution pour le plugin Gradle Expérimental, ça a marché pour moi...
Testé avec com.Android.outils.construire:gradle-expérimental:0.9.1
model {
...
android {
...
ndk {
...
stl = "c++_shared"
}
}
}
je ne pouvais pas utiliser c++_static
, il a donné à quelques erreurs au sujet indéfini des exceptions. Je suis donc retourné au gnustl_static
.
mais dans les sources NDK, dans sources/cxx-stl/llvm-libc++/src/string.cpp
, j'ai trouvé l'implémentation de to_string(int)
et j'ai essayé de la Copier dans mon code. Après quelques corrections ça a marché.
donc le dernier morceau de code que j'ai eu:
#include <string>
#include <algorithm>
using namespace std;
template<typename S, typename P, typename V >
inline
S
as_string(P sprintf_like, S s, const typename S::value_type* fmt, V a)
{
typedef typename S::size_type size_type;
size_type available = s.size();
while (true)
{
int status = sprintf_like(&s[0], available + 1, fmt, a);
if ( status >= 0 )
{
size_type used = static_cast<size_type>(status);
if ( used <= available )
{
s.resize( used );
break;
}
available = used; // Assume this is advice of how much space we need.
}
else
available = available * 2 + 1;
s.resize(available);
}
return s;
}
template <class S, class V, bool = is_floating_point<V>::value>
struct initial_string;
template <class V, bool b>
struct initial_string<string, V, b>
{
string
operator()() const
{
string s;
s.resize(s.capacity());
return s;
}
};
template <class V>
struct initial_string<wstring, V, false>
{
wstring
operator()() const
{
const size_t n = (numeric_limits<unsigned long long>::digits / 3)
+ ((numeric_limits<unsigned long long>::digits % 3) != 0)
+ 1;
wstring s(n, wchar_t());
s.resize(s.capacity());
return s;
}
};
template <class V>
struct initial_string<wstring, V, true>
{
wstring
operator()() const
{
wstring s(20, wchar_t());
s.resize(s.capacity());
return s;
}
};
string to_string(int val)
{
return as_string(snprintf, initial_string<string, int>()(), "%d", val);
}
pour Android Studio, ajoutez ceci dans build.gradle (Application Mobile)
externalNativeBuild {
cmake {
cppFlags "-std=c++11"
arguments "-DANDROID_STL=c++_static"
}
}