使用C ++和Android ndk / jni

时间:2011-06-21 09:26:57

标签: c++ android c java-native-interface android-ndk

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

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

这是我现在的问候世界的问候世界:

档案“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.

知道如何编译这个东西吗?

由于

6 个答案:

答案 0 :(得分:15)

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

来自 ANDROID-MK.html

  

请注意,C ++源文件的默认扩展名为“.cpp”。它是   但是可以通过定义变量来指定不同的一个   LOCAL_CPP_EXTENSION。不要忘记初始点(即'.cxx'会   工作,但不是'cxx')。

答案 1 :(得分:3)

您必须重新编译专门针对Android的所有本机库。您确实需要您计划使用的所有第三方本机库的源代码,因为通常当我们在Android之外编译和链接这些库时,它们会链接到glibc,但遗憾的是Android不会使用glibc到期liscence和性能问题。 Android使用名为glibc的{​​{1}}的淡化版本。对于大多数常用功能,它与glibc具有匹配的符号名称。但据我所知,libc没有与libc相关的某些功能,它肯定没有strings支持。如果您的本机库使用任何已弃用的功能,则必须通过使用posix支持的替代功能并相应地编写lib来为这些功能找到解决方法。

另外,正如你指出的那样,你将不得不使用NDK将Java(Android app / fwk)与原生世界(C ++)连接起来。

虽然这听起来很简单,但根据我的经验,在Android上编译本机库(Android移植)传统上非常耗费时间而且不能保证过度使用。

答案 2 :(得分:1)

关于你的编译错误,似乎你先把它称为“second.c”,然后将其重命名为“second.cpp”,但是在编译之前,目标文件中仍然有“second.c”名称(bdk) -build)你需要删除/ cygdrive / c / android-ndk-r5c / samples / two-libs / obj / local / armeabi / objs / twolib-second / directory

答案 3 :(得分:0)

  

错误:在'class'之前预期'=',',',';','asm'或'__ attribute __'

经典案例遗失';'在类关键字之前?想象

 int functionname(int p)
 class X { } ;

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

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

并且错误发生在someheader.h /或任何递归包含的文件/中的最后一个声明中;)

答案 4 :(得分:0)

执行命令

ndk-build clean
修改错误的Android.mk

,否则即使您已修复配置,构建仍可能继续失败。

我认为这就是OP的意思on this comment

答案 5 :(得分:0)

编辑Android.mk

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