Usar C++ con Android ndk/jni
Todas las muestras ndk solo hacen uso de funciones C básicas declaradas como externas en el encabezado y definidas en el archivo cpp. Luego, después de incluir el archivo de encabezado en el archivo C que contiene la devolución de llamada jni, todo funciona bien.
¿Es posible usar clases de C++ con android ndk? Mi aplicación no va a ser una actividad nativa, todavía tendrá una parte importante de Java, pero llamará a código C nativo para computación intensiva en CPU (ya escrito en C++, con clases y otras cosas de C++).
Aquí está mi hola-mundo como strcuture por ahora:
Archivo "primero.h "
#ifndef FIRST_H
#define FIRST_H
class Test
{};
#endif /* FIRST_H */
Archivo "segundo.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
Y finalmente Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libtwolib-second
LOCAL_SRC_FILES := second.cpp
include $(BUILD_SHARED_LIBRARY)
Bastante básico pero eso no compila. Segundo turno.cpp en a .el archivo c genera un error al incluir el archivo de encabezado, supongo que esto se debe a que no es un archivo C++.
error: expected '=', ',', ';', 'asm' or '__attribute__' before 'Test'
Haciéndolo .cpp plantea el siguiente error:
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.
Cualquier idea de cómo puedo hacer esa cosa compilar?
Gracias
6 answers
Puede usar C++ con NDK, pero los archivos con código C++ deben tener.extensión cpp.
Desde ANDROID-MK.html :
Tenga en cuenta que la extensión predeterminada para los archivos fuente de C++ es '.cpp". Es sin embargo, es posible especificar una diferente definiendo la variable LOCAL_CPP_EXTENSION. No olvide el punto inicial (es decir,'.cxx ' will trabajo, pero no "cxx').
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-21 09:44:00
Tendrás que recompilar todas las bibliotecas nativas específicamente para Android. Necesita el código fuente para todas las bibliotecas nativas de terceros que planea usar simplemente porque generalmente cuando compilamos y vinculamos estas bibliotecas fuera de Android están vinculadas a glibc
, pero desafortunadamente Android no usa glibc
debido a problemas de liscencia y rendimiento. Android usa una versión diluida de glibc
llamada libc
. Tiene nombres de símbolos coincidentes con glibc para la mayoría de las funcionalidades habituales. Pero en cuanto a sé que el libc no tiene alguna funcionalidad relacionada con strings
y definitivamente no tiene soporte para posix
. Si sus bibliotecas nativas están utilizando cualquiera de las funcionalidades obsoletas, tendrá que encontrar una solución alternativa para ellas utilizando la funcionalidad alternativa soportada por libc
y codificando sus bibliotecas en consecuencia.
Además, como bien has señalado, tendrás que usar el NDK para interconectar Java(Android app/fwk) con native world(C++).
Aunque esto suena bastante simple en mi experiencia compilando bibliotecas nativas en Android (Android porting) ha sido tradicionalmente muy lento sin garantía de éxito.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-21 09:31:56
Acerca de su error de compilación, parece que primero lo llamó "segundo.c "y más tarde lo renombró a" segundo.cpp "pero los archivos objeto todavía tienen el" segundo.c " nombre en ellos por lo que antes de compilar (bdk-build) que necesita para eliminar el *.o y *.d archivos en el directorio/cygdrive/c/android-ndk-r5c/samples/two-libs/obj/local/armeabi/objs/ twolib-second /
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-29 10:41:37
Error: esperado '=', ',', ';', 'asm' o '_ _ atributo _ _ 'antes de'clase'
Caso clásico de falta'; ' antes de la palabra clave class? Imagine
int functionname(int p)
class X { } ;
Esto podría llevar a su mensaje de compilador con bastante facilidad. Un factor de complicación común es cuando en realidad se ve como
#include "someheader.h"
class X { } ;
Y el error está en la última declaración dentro de someheader.h / o cualquier archivo incluido recursivamente/;)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-21 10:06:13
Ejecutar:
ndk-build clean
Después de modificar un Android.mk
incorrecto, o de lo contrario la compilación puede continuar fallando incluso si ha corregido la configuración.
Creo que esto es lo que el OP significaba en este comentario.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:46:11
Editar Android.mk
Modifique las instancias de LOCAL_SRC_FILES y elimine el./ desde el principio de cada línea.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-08 13:55:44