Невозможно включить заголовки C++, такие как вектор, в Android NDK

Когда я пытаюсь включить любой класс С++, такой как вектор, в свой проект Android NDK (используя последнюю версию NDK r5b), я получаю сообщение об ошибке, подобное следующему...

Compile++ thumb : test-libstl <= test-libstl.cpp /Users/nitrex88/Desktop/Programming/EclipseProjects/STLTest/jni/test-libstl.cpp:3:18: error: vector: No such file or directory

Другие люди, сообщившие об этой проблеме в Интернете, заявили об успехе, добавив

APP_STL := stlport_static

в свой файл Application.mk. Я сделал это, а также попробовал все возможные значения для APP_STL. Я очистил проект, запустил ndk-build clean, удалил папки obj и libs, и все же при компиляции он не может найти векторный класс. Я работаю над этим уже несколько недель (с тех пор как вышел NDK r5) и был бы очень признателен, если бы у кого-нибудь был совет. Спасибо!


person Nitrex88    schedule 04.02.2011    source источник
comment
Прежде всего, проверьте каталог android-ndk-r5\build\platforms\android-X\arch-arm\usr\include - действительно ли там находится vector?   -  person Seva Alekseyev    schedule 04.02.2011
comment
Нет это не так! Я мало что знаю о том, как работает NDK, кроме использования JNI и компиляции исходников. Как я могу заставить вектор быть там? Я вижу вектор в android-ndk-r5b/sources/cxx-stl/stlport/stlport, если это что-то значит. Спасибо за быстрый ответ, и я очень ценю это!   -  person Nitrex88    schedule 04.02.2011
comment
@seva Итак, я попытался запустить несколько инструментов для восстановления цепочки инструментов и предварительных сборок (файлы .sh в папке инструментов NDK), но все равно не смог заставить работать заголовки STL. Если я загружу свежий NDK с сайта Android, разве все не должно работать? Пробовал, свежая загрузка ничего не меняет. Можете ли вы предложить больше информации по этому вопросу?   -  person Nitrex88    schedule 06.02.2011
comment
[вот как я настроил STLPort для работы с Android Froyo.][1] [1]: stackoverflow.com/questions/1650963/ustl-or-stlport-for-android   -  person ZhangXuelian    schedule 03.11.2011
comment
[вот как я настроил STLPort для работы с Android Froyo.][1] [1]: stackoverflow.com/questions/1650963/ustl-or-stlport-for-android   -  person ZhangXuelian    schedule 03.11.2011
comment
@SevaAlekseyev что делать, когда нет vector? Я создал Application.mk внутри папки jni, поместил APP_:= stlport_static внутрь, но все равно не работает   -  person relaxxx    schedule 23.04.2012
comment
Вы можете просто включить #ifdef __cplusplus #endif во все файлы заголовков, в которых вы столкнулись с этой проблемой. __cplusplus будет определено для любой единицы компиляции, которая выполняется компилятором C++. Это работает очень хорошо. :)   -  person Muhammad Usman    schedule 04.04.2020


Ответы (8)


Это возможно. Вот несколько шагов:

В $PROJECT_DIR/jni/Application.mk:

APP_STL                 := stlport_static

Я пытался использовать stlport_shared, но безуспешно. То же самое с libstdС++.

В $PROJECT_DIR/jni/Android.mk:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := hello-jni
LOCAL_SRC_FILES := hello-jni.cpp
LOCAL_LDLIBS    := -llog

include $(BUILD_SHARED_LIBRARY)

Здесь нет ничего особенного, но убедитесь, что ваши файлы имеют формат .cpp.

В $PROJECT_DIR/jni/hello-jni.cpp:

#include <string.h>
#include <jni.h>
#include <android/log.h>

#include <iostream>
#include <vector>


#define  LOG_TAG    "hellojni"
#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)


#ifdef __cplusplus
extern "C" {
#endif

// Comments omitted.    
void
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
                                                  jobject thiz )
{
    std::vector<std::string> vec;

    // Go ahead and do some stuff with this vector of strings now.
}

#ifdef __cplusplus
}
#endif

Единственное, что меня здесь укусило, это #ifdef __cplusplus.

Смотрите каталоги.

Для компиляции используйте ndk-build clean && ndk-build.

person Sebastian Roth    schedule 08.02.2011
comment
Спасибо Спасибо!! Вы наконец решили мою проблему. Оказывается, у меня был Application.mk не в том месте! У меня он был в папке проекта, но не в папке JNI (я не уверен, почему, но с тех пор, как я начал разработку Android, я всегда думал, что он там). Увидев, что вы указали путь к Application.mk в папке jni, я понял. Спасибо, и вы получите награду! - person Nitrex88; 08.02.2011
comment
Простое создание нужного Application.mk решило проблему, но я вижу сообщение Android NDK: You might want to use $NDK/build/tools/build-stlport.sh. ПРИМЕЧАНИЕ: это не работало под cygwin - person Someone Somewhere; 09.02.2012
comment
привет, я могу создать приложение, которое использует вектор. - person CoDe; 29.02.2012
comment
привет, я добавил APP_STL := stlport_static в файл Application.mk, и он работает для моего приложения, но то же самое приложение, которое я включаю в Android Source, здесь оно дает мне класс вектора ошибки не найден .. во время компиляции кода. Пожалуйста, предложите мне любое представление об этом. - person CoDe; 29.02.2012
comment
Круто :) Это сработало и для меня. Достаточно было создать Application.mk. Спасибо :) - person Prashant Singh; 10.11.2012
comment
у меня нет файла Application.mk, и после создания файла со строкой, которую вы написали в ответе, я все еще получаю ошибки, такие как неразрешенное включение: ‹vector› для строки #include. что я должен делать? - person android developer; 21.07.2013
comment
@androiddeveloper, если у вас его нет, возможно, самое время его создать? - person Sebastian Roth; 28.07.2013
comment
@SebastianRoth забыл упомянуть, что я пробовал, но даже тогда у меня все еще была эта ошибка. не могли бы вы помочь? - person android developer; 28.07.2013
comment
Возможно, вы можете загрузить образец своего проекта на github и поделиться URL-адресом, тогда мы сможем взглянуть. - person Sebastian Roth; 29.07.2013
comment
extern C JNIEXPORT — добавьте это перед экспортируемыми функциями (в вашем проекте cpp) - person hB0; 05.11.2013
comment
конечно, этот файл .cpp и выбор способа его сборки в make-файле, #ifdefs является избыточным, и __cplusplus всегда следует определять в этом контексте? - person jheriko; 27.11.2013
comment
Это сработало, но, к сожалению, теперь другая часть выходит из строя, что было исправлено путем изменения APP_STL на c++_static. Теперь я получаю фатальную ошибку: поток: Нет такого файла или каталога #include ‹thread›. Я убрал эту ошибку, когда изменил APP_STL на c++_static - person Hunter-Orionnoir; 24.09.2015
comment
stlport_shared тоже работает, но может потребоваться добавить static { System.loadLibrary(stlport_shared); } в версиях до 4.3, согласно developer.android.com/ndk/guides/cpp. -support.html - person Yingpei Zeng; 04.05.2016
comment
Совет, который сработал для меня: если папки jni не существует, обязательно добавьте «APP_BUILD_SCRIPT: = Android.mk» в файл Application.mk. - person Santiago Villafuerte; 17.08.2016
comment
Вы можете просто включить #ifdef __cplusplus #endif во все файлы заголовков, в которых вы столкнулись с этой проблемой. __cplusplus будет определено для любой единицы компиляции, которая выполняется компилятором C++. Это работает очень хорошо. :) - person Muhammad Usman; 04.04.2020

Если вы используете студию Android и по-прежнему видите сообщение «ошибка: вектор: нет такого файла или каталога» (или другие ошибки, связанные с stl) при компиляции с использованием ndk, это может вам помочь.

В своем проекте откройте файл build.gradle модуля (не build.grade вашего проекта, а тот, который предназначен для вашего модуля) и добавьте «stl «stlport_shared»» в элемент ndk в defaultConfig.

Например:

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.2"

    defaultConfig {
        applicationId "com.domain.app"
        minSdkVersion 15
        targetSdkVersion 21
        versionCode 1
        versionName "1.0"

        ndk {
            moduleName "myModuleName"
            stl "stlport_shared"
        }
    }
}
person rlcoder    schedule 23.03.2015
comment
Почему stlport_shared, а не stlport_static? - person IgorGanapolsky; 11.05.2016

Я использую Android Studio, и по состоянию на 19 января 2016 года это помогло мне. (Похоже, что-то меняется каждый год или около того)

Перейдите: приложение -> Сценарии Gradle -> build.gradle (Модуль: приложение)

Затем в разделе model {... android.ndk {... и добавьте строку: stl = "gnustl_shared"

Нравится:

model {

    ...

    android.ndk {
        moduleName = "gl2jni"
        cppFlags.add("-Werror")
        ldLibs.addAll(["log", "GLESv2"])
        stl = "gnustl_shared"     //  <-- this is the line that I added
    }

    ...

}
person kynnysmatto    schedule 18.01.2016
comment
Эй, у меня возникла эта проблема с ffmpeg, на самом деле сборка ndk работает нормально и успешно генерирует файлы .so, но файлы заголовков отсутствуют. У вас есть какие-либо идеи об этом? (Я использую Android-студию с экспериментальным плагином Gradle) - person Pushpendra; 13.04.2016
comment
Это с экспериментальным плагином gradle? - person Sebastian Roth; 12.07.2016
comment
Почему gnustl_shared вместо gnustl_static? - person IgorGanapolsky; 18.07.2016
comment
Работает, я думаю, это следует выбрать в качестве ответа. - person Vishnudev K; 21.07.2016
comment
Я пробовал это с самой последней версией Android Studio 2.1.3, и, похоже, это не работает. Чтобы проверить это, я взял пример приложения HelloJNI, переименовал hello-jni.c в .cpp и добавил к нему #include ‹vector›. Я получаю сообщение об ошибке: fatal error: 'vector' file not found #include <vector> Требуются ли какие-либо дополнительные шаги после добавления stl=gnustl_static или gnustl_shared в файл gradle модуля? - person Sidelobe; 02.09.2016

Даже Себастьян дал там хороший ответ еще 3 года назад, я все же хотел бы поделиться здесь новым опытом, на случай, если вы столкнетесь с той же проблемой, что и я, в новой версии ndk.

У меня есть ошибка компиляции, например:

fatal error: map: No such file or directory
fatal error: vector: No such file or directory

Моя среда — android-ndk-r9d и adt-bundle-linux-x86_64-20140702. Я добавляю файл Application.mk в ту же папку jni и вставляю одну (и только одну) строку:

APP_STL := stlport_static

Но, к сожалению, это не решает мою проблему! Я должен добавить эти 3 строки в Android.mk, чтобы решить эту проблему:

ifndef NDK_ROOT
include external/stlport/libstlport.mk
endif

И я увидел хорошее совместное использование от здесь, в котором говорится, что "'stlport_shared' предпочтительный». Так что, возможно, лучше использовать stlport в качестве разделяемой библиотеки вместо статической. Просто добавьте следующие строки в Android.mk, а затем не нужно добавлять файл Application.mk.

ifndef NDK_ROOT
include external/stlport/libstlport.mk
endif
LOCAL_SHARED_LIBRARIES += libstlport

Надеюсь, это полезно.

person gary    schedule 18.08.2014
comment
Просто для ясности: когда вы говорите ту же папку jni, вы имеете в виду папку jni проекта Android? Я хочу убедиться, что нет другого места, о котором я должен знать. примечание: эта хорошая ссылка для обмена уже мертва :( - person Hunter-Orionnoir; 24.09.2015

Позвольте мне немного добавить к ответу Себастьяна Рота.

Ваш проект можно скомпилировать, используя ndk-build в командной строке после добавления кода, опубликованного Себастьяном. Но что касается меня, то в Eclipse были синтаксические ошибки, и у меня не было автодополнения.

Обратите внимание, что ваш проект должен быть преобразован в проект C/C++.

Как преобразовать проект C/C++< /а>

Чтобы устранить эту проблему, щелкните проект правой кнопкой мыши и выберите Свойства.

Выберите Общие C/C++ -> Пути и символы и включите ${ANDROID_NDK}/sources/cxx-stl/stlport/stlport в Включить каталоги.

Нажмите Да, когда появится диалоговое окно.

Диалог

До

До

После

После

Обновление №1

GNU C. Добавить каталоги, перестроить. В исходных файлах C не будет ошибок
GNU C++. Добавить каталоги, перестроить. В исходных файлах CPP не будет ошибок.

person Maksim Dmitriev    schedule 13.12.2013

Если вы используете ndk r10c или более позднюю версию, просто добавьте APP_STL=c++_static в Application.mk.

person clark.li    schedule 08.01.2015

Вот что вызвало проблему в моем случае (CMakeLists.txt):

set (CMAKE_CXX_FLAGS "...some flags...")

Это делает невидимыми все ранее определенные включаемые каталоги. После удаления/рефакторинга этой строчки все работает нормально.

person Fedorov7890    schedule 06.03.2019

В Android NDK перейдите в android-ndk-r9b>/sources/cxx-stl/gnu-libstdc++/4.X/include в Linux-машинах.

Я нашел решение по ссылке ниже http://osdir.com/ml/android-ndk/2011-09/msg00336.html

person Rojesh    schedule 27.11.2013