Android ndk std::to_string support

Android ndk std::to_string support

本文关键字:string support to std Android ndk      更新时间:2023-10-16

我正在使用android NDK r9d和工具链4.8,但我无法使用std::to_string函数,编译器抛出此错误:

 error: 'to_string' is not a member of 'std'

安卓 ndk 不支持此功能吗?我尝试APP_CPPFLAGS := -std=c++11但没有运气。

您可以尝试LOCAL_CFLAGS := -std=c++11,但请注意,并非所有 C++11 API 都可以在 NDK 的 gnustl 中使用。libc++ (APP_STL := c++_shared ) 提供了完整的 C++14 支持。

另一种方法是自己实现它。

#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) ;
}

在 NDK r9+ 中,您可以使用 llvm-libc++,它完全支持 cpp11。

在您的 Application.mk 中,您必须添加:

APP_STL:=c++_static 

APP_STL:=c++_shared

Gradle

如果您正在寻找 Gradle 构建系统的解决方案。看看这个答案。

简短的回答。

添加字符串

arguments "-DANDROID_STL=c++_shared"

在你的build.gradle.喜欢

android {
  ...
  defaultConfig {
    ...
    externalNativeBuild {
      cmake {
        ...
        arguments "-DANDROID_STL=c++_shared"
      }
    }
  }
  ...
}
实验性

Gradle 插件

如果您正在寻找实验性 Gradle 插件的解决方案,这对我有用......

使用 com.android.tools.build 测试:gradle-experimental:0.9.1

model {
  ...
  android {
    ...
    ndk {
      ...
      stl = "c++_shared"
    }
  }
}

我不能使用c++_static,它给出了一些关于未定义异常的错误。所以我回到了gnustl_static.

但是在 NDK 源代码中,在 sources/cxx-stl/llvm-libc++/src/string.cpp 中,我找到了to_string(int)的实现并尝试将其复制到我的代码中。经过一些更正后,它起作用了。

所以我有的最后一段代码:

#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);
}

对于 Android Studio,请在 build.gradle (Mobile App) 中添加此内容

externalNativeBuild {
    cmake {
        cppFlags "-std=c++11"
        arguments "-DANDROID_STL=c++_static"
    }
}