2013-07-30 5 views
20

C++ 11 có hai hàm chuyển đổi chuỗi mới thành unsigned longlong long: std::stoul()std::stoll().Làm thế nào để sử dụng std :: stoul và std :: stoull trong Android?

NDK r9 Android gần đây giới thiệu trình biên dịch Clang 3.3 được gọi là tính năng C++ 11 hoàn chỉnh. Có các nguyên mẫu cho các hàm này nằm sâu bên trong NDK, tuy nhiên tôi không thể sử dụng chúng.

Tôi cần làm gì để sử dụng chúng?

P.S. Tôi đã làm LOCAL_CPPFLAGS += -std=c++11

+3

Có thể tương tự như http://stackoverflow.com/questions/15616254/enable-c11-support-on-android này. nhưng thay vào đó hãy sử dụng thư viện clangs C++ 11. (Tôi nghĩ rằng '-stdlib = libC++ -std = C++ 11' của nó cho LOCAL_CFLAGS) – FDinoff

+0

Tôi đã làm' '-std = C++ 11'' –

+0

' -stdlib = libC++ 'cũng cần đảm bảo bạn thử nó – aaronman

Trả lời

36

Lý do tại sao bạn không thể sử dụng các chức năng được bắt nguồn từ khá sâu và tiếc là hiện không thể giải quyết được.

Nhìn vào libs/armeabi-v7a/include/bits/c++config.h tập tin trong stdlibc gnu ++ thư mục, bạn sẽ thấy điều này:

... 
/* 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 */ 
... 

ở trên, kết hợp với đoạn mã sau đây từ bits/basic_string.h phép thuật tin xấu:

... 
#if (defined(__GXX_EXPERIMENTAL_CXX0X__) && defined(_GLIBCXX_USE_C99) \ 
    && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF)) 

/* The definitions of Numeric Conversions [string.conversions] */ 
#endif 
... 

Do đó, các hàm này không thể sử dụng được trong NDK.

Nguyên nhân Root: Các nguyên nhân gốc rễ có vẻ là rằng việc sử dụng chức năng C99 đã bị vô hiệu hóa trong stdlibc GNU ++ trên nền tảng armeabi-v7a do thực tế các sự libc Bionic không hỗ trợ toán học phức tạp (tiêu chuẩn C thư viện trên Android là Bionic).

Sửa lỗi (chưa kiểm tra): Khám phá CrystaX's Android NDK có vẻ như có phần mở rộng trên NDK của Android Vanilla.

Lưu ý:__GXX_EXPERIMENTAL_CXX0X__ được xác định bằng cách thêm -std=gnu++11-APP_CXXFLAGS hoặc LOCAL_CXXFLAGS

Chi tiết đăng nhập thử nghiệm: xây dựng sử dụng phiên bản NDK 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 trên Nexus 4 (Android 4.3):

[email protected]:/ $ /data/local/tmp/cxx11 
__GXX_EXPERIMENTAL_CXX0X__ defined. 
_GLIBCXX_USE_C99 not defined. 
_GLIBCXX_HAVE_BROKEN_VSWPRINTF not defined. 
No support for stoll/stoul. 
+0

Bất kỳ cơ hội nào để thay thế stdlib? –

+0

@SergeyK. Hãy thử [NDK Android của CrystaX] (http://www.crystax.net/android/ndk.php), dường như có một số bản sửa lỗi trên NDK của Vanilla Android. Tôi cũng đang tìm cách khám phá nó. – Samveen

+0

Bạn đã thử NDK r9 chưa? Có lẽ chúng ta có thể xác định _GLIBCXX_USE_C99 theo cách thủ công? –

5

Thêm:

APP_STL: = C++ _static

to Application.mk đã khắc phục sự cố của tôi về việc không thể truy cập std :: stoi() (sử dụng gcc 4.8.4).

giải pháp qua Daniel Tavares, từ số Google Groups post này.

+0

Điều này cũng khắc phục sự cố truy cập vào các biến 'unsigned long' và' long long' của các hàm ('stoul' và' stoll')? – Samveen

+0

Giải pháp đó đã giúp tôi với stoul(). Cảm ơn. – Stranger