it-roy-ru.com

Используйте C++ с Android ndk/jni

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

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

Вот мой привет мир, как 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.

Любая идея, как я могу заставить эту вещь компилировать?

Спасибо

34
user745189

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

От Android-MK.html :

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

15
Michael

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

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

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

3
Alok Save

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

1
Bush

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

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

 int functionname(int p)
 class X { } ;

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

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

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

0
sehe

Бежать:

ndk-build clean

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

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

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

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

0
QAlexkander Nicholson