Используйте C ++ с Android ndk / jni - PullRequest
34 голосов
/ 21 июня 2011

Все примеры ndk используют только базовые функции C, объявленные в заголовке как extern и определенные в файле cpp.Затем после включения заголовочного файла в файл C, содержащий обратный вызов jni, все работает нормально.

Можно ли использовать классы C ++ с android ndk?Мое приложение не будет нативной деятельностью, оно будет по-прежнему иметь важную часть Java, но оно будет вызывать нативный C-код для ресурсоемких вычислений (уже написанных на C ++ с классами и прочим C ++).

Вот мой hello-world как strcuture на данный момент:

Файл "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)

Довольно простой, но не компилируется.Включение файла second.cpp в файл .c приводит к ошибке при включении файла заголовка. Я полагаю, это связано с тем, что это не файл 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 ]

15 голосов
/ 21 июня 2011

Вы можете использовать C ++ с NDK, но файлы с кодом C ++ должны иметь расширение .cpp.

С ANDROID-MK.html :

Примечаниечто расширение по умолчанию для исходных файлов C ++ - '.cpp'.Однако можно указать другой, определив переменную LOCAL_CPP_EXTENSION.Не забудьте начальную точку (т. Е. «.Cxx» будет работать, но не «cxx»).

3 голосов
/ 21 июня 2011

Вам придется перекомпилировать все нативные библиотеки специально для Android.Вам нужен исходный код для всех сторонних собственных библиотек, которые вы планируете использовать просто потому, что обычно, когда мы компилируем и связываем эти библиотеки вне Android, они связаны с glibc, но, к сожалению, Android не использует glibc из-за различий и производительности.проблемы.Android использует разбавленную версию glibc под названием libc.Он имеет соответствующие имена символов для glibc для большинства обычных функций.Но, насколько я знаю, libc не имеет некоторых функций, связанных с strings, и определенно не имеет поддержки posix.Если ваши нативные библиотеки используют какие-либо устаревшие функции, вам придется найти обходной путь для них, используя альтернативные функции, поддерживаемые libc, и соответствующим образом кодируя свои библиотеки.

Кроме того, как вы правильно заметили, вам придется использовать NDK для взаимодействия Java (Android app / fwk) с собственным миром (C ++).

Хотя это звучит довольно просто, по моему опыту, компиляция нативных библиотек на Android (портирование Android) традиционно занимала много времени без гарантии успеха.

1 голос
/ 29 октября 2012

Что касается вашей ошибки компиляции, кажется, что вы сначала назвали ее «second.c», а затем переименовали в «second.cpp», но в объектных файлах все еще есть имя «second.c», так что перед компиляцией (bdk -build) вам нужно удалить файлы * .o и * .d в / cygdrive / c / android-ndk-r5c / samples / two-libs / obj / local / armeabi / objs / twolib-second / directory

0 голосов
/ 08 июля 2017

Редактировать Android.mk

Изменить экземпляры LOCAL_SRC_FILES и удалить ./ в начале каждой строки.

0 голосов

Пробег:

ndk-build clean

после неправильного изменения Android.mk, иначе сборка может продолжить сбой, даже если вы исправили конфигурацию.

Я думаю, это то, что имел в виду ОП в этом комментарии .

0 голосов
/ 21 июня 2011

ошибка: ожидается '=', ',', ';', 'asm' или '__ attribute __' перед 'class'

Классический случай отсутствия ';' перед ключевым словом класса? Представьте

 int functionname(int p)
 class X { } ;

Это может довольно легко привести к сообщению вашего компилятора. Общим усложняющим фактором является то, что на самом деле это выглядит как

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

и ошибка в последнем объявлении внутри someheader.h / или в любом рекурсивно включенном файле /;)

...