无法在Android NDK中包含C++头文件,如vector

84

当我尝试在我的Android NDK项目中包含任何C ++类,例如vector(使用最新的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文件夹,但是当我编译时仍然找不到vector类 。 我已经在处理这个问题上工作了几周了(自从NDK r5发布以来),如果有人有任何建议,我将非常感激。谢谢!


2
首先,请检查android-ndk-r5\build\platforms\android-X\arch-arm\usr\include目录 - 是否确实存在vector - Seva Alekseyev
2
不是这样的!除了使用JNI和编译源代码之外,我对NDK的工作原理并不了解。我怎么才能使向量存在?如果那有任何意义,我在android-ndk-r5b/sources/cxx-stl/stlport/stlport中看到了向量。感谢您的快速回复,我非常感激! - Nitrex88
2
@seva,我尝试运行了一堆重建工具链和预构建工具(NDK 工具文件夹中的 .sh 文件),但仍然无法让 STL 标头文件正常工作。如果我从 Android 网站上新下载 NDK,难道不应该一切都能正常工作吗?我已经尝试过了,重新下载并没有改变任何事情。你能提供更多关于这个问题的见解吗? - Nitrex88
这是我如何配置STLPort以使其与Android Froyo兼容的方法。 - ZhangXuelian
这是我如何配置STLPort以使其与Android Froyo兼容的方法。 - ZhangXuelian
显示剩余2条评论
9个回答

122

是可以做到的。以下是一些步骤:

$PROJECT_DIR/jni/Application.mk 中:

APP_STL                 := stlport_static
我尝试使用stlport_shared,但没有成功。libstdc++也是如此。
在$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。

5
谢谢,谢谢!你终于解决了我的问题。原来是我的Application.mk文件放错位置了!我把它放在了项目文件夹中而不是JNI文件夹中(我不确定为什么,但自从开始进行Android开发以来,我一直认为应该放在那里)。看到你将Application.mk的路径放在了jni文件夹中,让我意识到了这一点。感谢你,你会得到奖金! - Nitrex88
2
只需创建必要的Application.mk即可解决问题,但我看到消息“Android NDK: You might want to use $NDK/build/tools/build-stlport.sh”。注意:在cygwin下这种方法不起作用。 - Someone Somewhere
1
也许你可以将你的项目样例上传到Github并分享URL,这样我们就可以查看了。 - Sebastian Roth
extern "C" JNIEXPORT -- 在您的 cpp 项目中,在导出函数之前添加此内容 - hB0
这个文件的后缀是.cpp,而且在makefile中选择如何构建它时,#ifdef可能是多余的,因为在这种情况下__cplusplus应该总是被定义的。 - jheriko
显示剩余10条评论

20
如果您正在使用Android Studio并且在使用NDK编译时仍然看到“error:vector:No such file or directory”(或其他与STL相关的错误)消息,则可能会帮助您。在您的项目中,打开模块的build.gradle文件(不是您项目的build.gradle文件,而是适用于您模块的那个),并在defaultConfig的ndk元素中添加“stl“stlport_shared”。例如:
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"
        }
    }
}

1
为什么使用 stlport_shared 而不是 stlport_static - IgorGanapolsky

9

我正在使用Android Studio,截至2016年1月19日,以下内容对我有用。(这似乎是每年都会更改的内容)

前往: 应用程序 -> Gradle Scripts -> build.gradle (Module: app)

然后,在 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
    }

    ...

}

嘿,我在使用ffmpeg时遇到了问题。实际上,ndk构建正常工作,并成功生成.so文件,但头文件却丢失了。你有任何想法吗?(我正在使用带有gradle实验性插件的Android Studio) - Pushpendra
那是使用 gradle-experimental 插件吗? - Sebastian Roth
为什么要使用gnustl_shared而不是gnustl_static - IgorGanapolsky
好的,我想这应该被选为答案。 - Vishnudev K
我尝试在最新的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文件后,是否需要任何其他步骤? - Sidelobe

5
如果您正在使用ndk r10c或更高版本,只需在Application.mk中添加APP_STL=c++_static即可。

4
即使Sebastian在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。 我在同一个jni文件夹中添加了Application.mk文件,并插入了一行(仅一行):

APP_STL := stlport_static

但是不幸的是,它并不能解决我的问题!我必须将这三行代码添加到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

希望这对您有所帮助。

只是为了明确,当你说“同一个jni文件夹”时,你是指安卓项目的jni文件夹吗?我想确保没有其他地方需要我知道。顺便说一句:那个好的分享链接现在已经失效了:( - Hunter-Orionnoir

4

让我为Sebastian Roth的回答增加一点内容。

在添加Sebastian发布的代码后,您可以使用命令行中的ndk-build编译您的项目。但对于我来说,Eclipse中存在语法错误,而且我没有代码完成功能。

请注意,您的项目必须转换为C/C++项目。

如何转换为C/C++项目

要解决此问题,请右键单击您的项目,单击属性

选择C/C++通用 -> 路径和符号,将${ANDROID_NDK}/sources/cxx-stl/stlport/stlport包含到包含目录

当出现对话框时,请单击

Dialog

之前

Before

之后

After

更新 #1

GNU C. 添加目录,重新构建。C源文件中不会有任何错误。
GNU C++. 添加目录,重新构建。CPP源文件中不会有任何错误。


1
这是我遇到的问题的原因(CMakeLists.txt):
set (CMAKE_CXX_FLAGS "...some flags...")

它会使之前定义的所有包含目录都变为不可见。 移除/重构此行后,一切正常。

0

0

打开 build.grade(模块)并进行一些编辑(删除一个字母并重新添加)。这样操作栏会自动出现。现在,点击“好的,应用建议”。现在,每个 cpp 和 headers 文件中的问题都已解决。

enter image description here.


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接