У меня есть приведенный ниже исходный код с использованием std :: future.

#include<future>
std::future<int> A;

Однако, когда я пытаюсь скомпилировать его с помощью NDK_TOOLCHAIN_VERSION: = 4.8 в файле Application.mk, он выдает ошибку «std :: future A» имеет неполный тип и т. Д. »

Я попытался найти future.h в папке android-ndk-r9c, однако мне не удалось его найти. Кто-нибудь знает, поддерживает ли NDK вообще std :: future? Если да, то в какой версии есть эта поддержка?

2
pree 24 Май 2014 в 04:06
1
Вы должны искать файл с именем future, а не future.h, в стиле STL.
 – 
Alex Cohn
6 Июн 2014 в 23:08

3 ответа

Лучший ответ

Как упоминалось в одном из моих комментариев выше, я могу скомпилировать его, указав armeabi-v7a в качестве цели вместо armeabi.

NDK_TOOLCHAIN_VERSION := 4.8
APP_STL := gnustl_static
APP_ABI :=armeabi-v7a
0
pree 26 Июл 2014 в 02:19

Кажется, что std :: future недоступен ни в одной библиотеке stl и компиляторах с ndk-r9c.

Начиная с ndk r9d, вы можете использовать библиотеку libc ++ llvm. Поддержка описывается как «экспериментальная», но, похоже, работает достаточно хорошо.

Вместо выбранной в настоящее время библиотеки STL (полагаю, gnustl?) Используйте c++_shared или c++_static в своем Application.mk , например:

APP_ABI := all APP_STL := c++_shared NDK_TOOLCHAIN_VERSION := clang

Если вы столкнетесь с некоторыми проблемами выполнения статической версии, вы можете добавить LIBCXX_FORCE_REBUILD := true в Application.mk, чтобы принудительно перестроить его должным образом.

6
ph0b 27 Май 2014 в 20:16
1
Однако я попробовал вышеприведенное решение, когда я указываю APP_STL := c++_shared или c++_static и TOOLCHAIN_VERSION:= 4.8, он выдает некоторую ошибку «фатальная ошибка: ext/atomicity.h: нет такого файла или каталога». Кроме того, когда я даю TOOLCHAIN_VERSION := clang, он выдает ошибку «недопустимый аргумент -std=gnustl++11, не разрешенный с C/ObjC». Есть идеи, что мне не хватает?
 – 
pree
4 Июн 2014 в 04:08
1
При использовании clang -std=c++11 используется по умолчанию и работает, но gnustl++11 не поддерживается. Чтобы иметь ext/atomicity.h с NDK, вам нужно использовать gnustl_shared или gnustl_static.. но в этом случае у вас не будет std::future. Вы не должны смешивать эти библиотеки, вам нужно выбрать ту, которая вам больше всего нужна.
 – 
ph0b
4 Июн 2014 в 18:36
Я понимаю. Неужели нельзя использовать оба?
 – 
pree
4 Июн 2014 в 19:41
Это почти невозможно, и в любом случае это сделало бы это возможным: это потребовало бы серьезных модификаций вашего кода и все еще могло содержать ошибки.
 – 
ph0b
4 Июн 2014 в 20:24
1
Я экспериментировал с разными параметрами, и когда я указываю NDK_TOOLCHAIN_VERSION := 4.8, APP_STL := gnustl_static и APP_ABI:=armeabi-v7a, я не получаю ошибок компиляции, и мой код работает. У меня были все эти проблемы с APP_ABI:=armeabi. Однако не в состоянии понять полную аргументацию.
 – 
pree
5 Июн 2014 в 00:53

@pree: в настоящее время я экспериментирую с теми же настройками в Application.mk:

APP_ABI := armeabi-v7a

APP_STL := gnustl_static

APP_CPPFLAGS := -frtti --std=c++11

NDK_TOOLCHAIN_VERSION := 4.8

Однако, хотя мой код работает нормально на Nexus 10, приложение зависает на моем телефоне LG.

РЕДАКТИРОВАТЬ: Я сузил проблему. Код, который я использую, следующий:

auto task1 = std::packaged_task<void()>([]() {
    LOG_INFO("Task1 starting");
    sleep(5);
    LOG_INFO("Task1 finishing");
});
auto fut1 = task1.get_future();

auto task2 = std::packaged_task<void()>([]() {
    LOG_INFO("Task2 starting");
    sleep(10);
    LOG_INFO("Task2 finishing");
});
auto fut2 = task2.get_future();

std::thread([&](){task1();}).detach();
std::thread([&](){task2();}).detach();

LOG_INFO("waiting for task1");
fut1.wait();
LOG_INFO("waiting for task1 done");

LOG_INFO("waiting for task2");
fut2.wait();
LOG_INFO("waiting for task2 done");

На Nexus 10 этот код дает следующий результат:

 18:14:15.365: waiting for task1
 18:14:15.365: Task1 starting
 18:14:15.365: Task2 starting
 18:14:20.370: Task1 finishing
 18:14:20.370: waiting for task1 done
 18:14:20.370: waiting for task2
 18:14:25.365: Task2 finishing
 18:14:25.365: waiting for task2 done

На другом устройстве (телефоне LG) я получаю следующий вывод:

 18:23:21.999: Task1 starting
 18:23:21.999: waiting for task1
 18:23:26.999: Task1 finishing
 18:23:26.999: waiting for task1 done
 18:23:26.999: waiting for task2
 18:23:26.999: Task2 starting
 18:23:37.178: Task2 finishing
 18:23:37.178: waiting for task2 done

Это означает, что на устройстве LG вторая задача ожидает завершения первой, пока не запустится. Однако проблема, похоже, исходит из std :: Pack_task, а не из std :: future, потому что следующий код ведет себя должным образом на обоих устройствах:

std::promise<void> promise1;
auto task1 = std::function<void()>([&]() {
    LOG_INFO("Task1 starting");
    sleep(5);
    promise1.set_value();
    LOG_INFO("Task1 finishing");
});
auto fut1 = promise1.get_future();

std::promise<void> promise2;
auto task2 = std::function<void()>([&]() {
    LOG_INFO("Task2 starting");
    sleep(10);
    promise2.set_value();
    LOG_INFO("Task2 finishing");
});
auto fut2 = promise2.get_future();

std::thread([&](){task1();}).detach();
std::thread([&](){task2();}).detach();

LOG_INFO("waiting for task1");
fut1.wait();
LOG_INFO("waiting for task1 done");

LOG_INFO("waiting for task2");
fut2.wait();
LOG_INFO("waiting for task2 done");

Может я здесь что-то делаю не так?

3
ArtKorchagin 28 Ноя 2015 в 03:05
А что если использовать APP_ABI := armeabi? тогда он работает на обоих устройствах?
 – 
pree
5 Июн 2014 в 22:40
1
Нет. В этом случае он даже не компилируется.
 – 
CodeKonditor
5 Июн 2014 в 22:41
Ой. это потому, что вы используете std::future и т. д.?
 – 
pree
5 Июн 2014 в 22:42
Да. Я получаю сообщения об ошибках типа "агрегат 'std::future test' имеет неполный тип и не может быть определен".
 – 
CodeKonditor
5 Июн 2014 в 23:06
Как вы думаете, вы можете проверить информацию об оборудовании на вашем телефоне LG? Один из способов проверить это — загрузить приложение с информацией о системе Android с рынка. Перейдите на вкладку «Система», а затем «Информация о сборке». Он покажет вам две вещи. ЦП ABI и ЦП ABI2. Вы можете проверить оба?
 – 
pree
6 Июн 2014 в 01:20