Use C++ with Android ndk/jni



所有ndk示例都只使用在标头中声明为extern并在cpp文件中定义的基本C函数。然后,在包含jni回调的C文件中包含头文件之后,一切都正常。

有可能在android ndk中使用C++类吗?我的应用程序不会是本机活动,它仍然有一个重要的java部分,但它将调用本机C代码进行CPU密集型计算(已经用C++编写,带有类和其他C++内容)。

这是我现在的hello世界式结构:

文件"first.h"

#ifndef FIRST_H
#define FIRST_H
class Test
{};
#endif /* FIRST_H */

文件"second.cpp"

#include <jni.h>
#include "first.h"
#ifdef __cplusplus
extern "C" {
#endif
jint Java_com_example_twolibs_TwoLibs_add( JNIEnv*  env,
                                      jobject  this,
                                      jint     x,
                                      jint     y )
{
    Test t;
    return 0;
}
#ifdef __cplusplus
}
#endif

最后是Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE    := libtwolib-second
LOCAL_SRC_FILES := second.cpp
include $(BUILD_SHARED_LIBRARY)

很基本,但它不编译。在.c文件中打开second.cpp会在包含头文件时引发错误,我想这是因为它不是c++文件。

error: expected '=', ',', ';', 'asm' or '__attribute__' before 'Test'

将其设为.cpp会引发以下错误:

make: *** No rule to make target `/cygdrive/c/android-ndk-r5c/samples/twolibs/jni/second.c', needed by `/cygdrive/c/android-ndk-r5c/samples/two-libs/obj/local/armeabi/objs/twolib-second/second.o'.  Stop.

你知道我怎样才能把它编译出来吗?

感谢

您可以将C++与NDK一起使用,但带有C++代码的文件必须具有.cpp扩展名。

来自ANDROID-MK.html

请注意,C++源文件的默认扩展名是".cpp"但是,可以通过定义变量来指定不同的变量LOCAL_CPP_EXTENSION。不要忘记起始点(即".cxx"将工作,但不是"cxx")。

您必须重新编译所有专门针对Android的本地库。您确实需要计划使用的所有第三方原生库的源代码,因为通常当我们在Android之外编译和链接这些库时,它们会链接到glibc,但不幸的是,由于兼容性和性能问题,Android没有使用glibc。安卓系统使用了一个名为libc的淡化版glibc。对于大多数常用功能,它具有与glibc匹配的符号名称。但据我所知,libc没有一些与strings相关的功能,也肯定没有一些posix支持。如果您的本机库正在使用任何不推荐使用的功能,则必须通过使用libc支持的替代功能并相应地对库进行编码来找到解决方法。

此外,正如您正确指出的,您将不得不使用NDK将Java(Android应用程序/fwk)与原生世界(C++)连接起来。

尽管这听起来很简单,但根据我的经验,在Android上编译本地库(Android移植)传统上非常耗时,无法保证成功。

关于您的编译错误,似乎您首先将其称为"second.c",后来将其重命名为"second.cpp",但对象文件中仍然有"second.cp"名称,因此在编译(bdk构建)之前,您需要删除/cygdrive/c/android-ndk-r5c/samples/two-libs/obj/local/armeabi/objs/twolib second/directory 中的*.o和*.d文件

错误:应为"=",",",";","asm'或'__attribute__'在'class'之前

缺少";"的典型情况在class关键字之前?想象一下

 int functionname(int p)
 class X { } ;

这可能很容易导致您的编译器消息。一个常见的复杂因素是它实际上看起来像

 #include "someheader.h"
 class X { } ;

错误出现在someheader.h/或任何递归包含的文件/;内的最后一个声明中)

运行:

ndk-build clean

修改错误的Android.mk之后,否则即使修复了配置,构建也可能继续失败。

我想这就是OP对这条评论的意思。

编辑Android.mk

修改LOCAL_SRC_FILES的实例并删除。/从每一行的开头。

最新更新