opencv在交叉编译的时候的一些常见报错和处理---How to use std::stoul and std::stoull in Android?
C++11 has two new string conversion functions into unsigned long
and long long
: std::stoul()
and std::stoll()
.
The recent Android NDK r9 introduces Clang 3.3 compiler which is said to be C++11 feature complete. There are prototypes for these functions deep inside NDK, however I cannot use them.
What do I need to do to use them?
P.S. I already do LOCAL_CPPFLAGS += -std=c++11
2 Answers
The reason why you cannot use the functions is quite deep rooted, and unfortunately currently unsolvable.
Looking into the libs/armeabi-v7a/include/bits/c++config.h
file in the gnu stdlibc++ folder, you'll see this:
...
/* Define if C99 functions or macros from <wchar.h>, <math.h>, <complex.h>,
<stdio.h>, and <stdlib.h> can be used or exposed. */
/* #undef _GLIBCXX_USE_C99 */
...
The above, in conjunction with the following snippet from bits/basic_string.h
spells bad news:
...
#if (defined(__GXX_EXPERIMENTAL_CXX0X__) && defined(_GLIBCXX_USE_C99) \
&& !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
/* The definitions of Numeric Conversions [string.conversions] */
#endif
...
Thus, these functions are unusable in the NDK.
Root Cause: The root cause seems to be that the C99 functionality usage has been disabled in the GNU stdlibc++ on the armeabi-v7a platform due to the fact the the Bionic libc does not support complex math (the standard C library on Android is Bionic).
Possible Fix (untested): Explore CrystaX's Android NDK which seems to have extensions over the Vanilla Android NDK.
Note: __GXX_EXPERIMENTAL_CXX0X__
is defined by adding -std=gnu++11
to APP_CXXFLAGS
or LOCAL_CXXFLAGS
Detailed Test log: Built using NDK version r8e
jni/Application.mk:
APP_STL := gnustl_static
APP_CXXFLAGS += -std=gnu++11
NDK_TOOLCHAIN_VERSION := 4.7
jni/Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := cxx11
LOCAL_SRC_FILES := cxx11.cpp
include $(BUILD_EXECUTABLE)
jni/cxx11.cpp:
#include <iostream>
#include <string>
int main(int argc, char* argv[]) {
#if defined(__GXX_EXPERIMENTAL_CXX0X__)
std::cout<<"__GXX_EXPERIMENTAL_CXX0X__ defined."<<std::endl;
#else
std::cout<<"__GXX_EXPERIMENTAL_CXX0X__ not defined."<<std::endl;
#endif
#if defined(_GLIBCXX_USE_C99)
std::cout<<"_GLIBCXX_USE_C99 defined."<<std::endl;
#else
std::cout<<"_GLIBCXX_USE_C99 not defined."<<std::endl;
#endif
#if defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF)
std::cout<<"_GLIBCXX_HAVE_BROKEN_VSWPRINTF defined."<<std::endl;
#else
std::cout<<"_GLIBCXX_HAVE_BROKEN_VSWPRINTF not defined."<<std::endl;
#endif
#if (defined(__GXX_EXPERIMENTAL_CXX0X__) && defined(_GLIBCXX_USE_C99) \
&& !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
std::string s="1";
std::cout<<"ll:"<<std::stoll(s)<<std::endl<<"ul:"<<std::stoul(s)<<std::endl;
#else
std::cout<<"No support for stoll/stoul."<<std::endl;
#endif
return(0);
}
Output on Nexus 4 (Android 4.3):
u0_a51@mako:/ $ /data/local/tmp/cxx11
__GXX_EXPERIMENTAL_CXX0X__ defined.
_GLIBCXX_USE_C99 not defined.
_GLIBCXX_HAVE_BROKEN_VSWPRINTF not defined.
No support for stoll/stoul.
-
-
@SergeyK. Try CrystaX's Android NDK, which seems to have some fixes over the Vanilla Android NDK. I am looking to explore it as well.– SamveenAug 8, 2013 at 11:43
-
Have you tried NDK r9? Maybe we can define _GLIBCXX_USE_C99 manually? Aug 8, 2013 at 11:44
-
@SergeyK. Naah. Already tried
LOCAL_CFLAGS := -D _GLIBCXX_USE_C99=1
. It's a very deep-rooted problem.– SamveenAug 8, 2013 at 11:46 -
Adding:
APP_STL := c++_static
to Application.mk fixed my issue of not being able to access std::stoi() (using gcc 4.8.4).
solution via Daniel Tavares, from this Google Groups post.
-
Did this also fix the issue of access to the
unsigned long
andlong long
variants of the functions(stoul
andstoll
)?– SamveenFeb 22, 2016 at 5:14 -
每一个不曾起舞的日子,都是对生命的辜负。
But it is the same with man as with the tree. The more he seeks to rise into the height and light, the more vigorously do his roots struggle earthward, downward, into the dark, the deep - into evil.
其实人跟树是一样的,越是向往高处的阳光,它的根就越要伸向黑暗的地底。----尼采
-stdlib=libc++ -std=c++11
for the LOCAL_CFLAGS)-std=c++11
-stdlib=libc++
is also needed make sure you try it-E
to show the preprocessor output you can see thatbits/basic_string.h
is included and that appears to be wherestoll
is defined howeverstoll
does not appear in the preprocessor output.