https://github.com/crissalvarezh/addcodigocenandroid
Proyecto de ejemplo para integrar código nativo en C en Android.
https://github.com/crissalvarezh/addcodigocenandroid
android c cpp java jni jni-android ndk
Last synced: 3 months ago
JSON representation
Proyecto de ejemplo para integrar código nativo en C en Android.
- Host: GitHub
- URL: https://github.com/crissalvarezh/addcodigocenandroid
- Owner: CrissAlvarezH
- Created: 2019-08-06T14:27:49.000Z (almost 7 years ago)
- Default Branch: master
- Last Pushed: 2019-08-20T16:35:11.000Z (almost 7 years ago)
- Last Synced: 2025-06-09T23:03:31.913Z (about 1 year ago)
- Topics: android, c, cpp, java, jni, jni-android, ndk
- Language: Makefile
- Homepage:
- Size: 5.94 MB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Descripción
Este proyecto se creó a modo de ejemplo para integrar codigo C/C++ en un proyecto de Android utilizando JNI y NDK.
A continuación están los pasos a seguir para lograr este integración.
# Demostración
La aplicación Android suma dos numeros enteros, cada vez que se hace un cambio en alguno de los numero se realiza de nuevo la suma, esta
suma está hecha en el lenguaje C.

# Guía
Esta guía está separada en varias partes, la integración de codigo C en el cual
muestro como escribir codigo C en un proyecto de Android, la creación de las librerías compartidas `.so`, el consumo de dichas librerias, la importación de la librería en un proyecto distinto al donde fue construida y por ultimo usaremos codigo C++ en vez de C y
agregaremos logs para verlos en el LogCat de Android Studio.
## Integración con codigo C

Empezamos creando una clase en Java que contendrá los metodos que se escribirán en C. Como puedes notar utilizamos la palabra reservada
`native` para declarar el metodo, tambien puedes notar que no tiene cuerpo, esto es porque el cuerpo se lo definiremos en C.

Compilamos la clase que acabamos de crear utilizando `javac`, esto nos dará como resultado un `.class`

Ahora creamos el fichero de cabecera JNI para dicha clase, esto lo hacemos con el comando
`javah -c java .`, posteriormente
creamos un directorio llamado `jni` y movemos nuestro `.h`, recién creado, dentro.

Al abrir el archivo podemos ver que contiene la función que hemos declarado en `ClaseNativa.java`, pero su nombre tiene la siguiente estructura
`Java___`.

Ahora debemos crear el codigo C asociado a esa cabecera, para esto copiamos el archivo y lo pegamos en la misma carpeta pero le cambiamos la
extención de `.h` a `.c` y le hacemos los siguientes cambios

En el archivo `.c` que creamos en el anterior paso vamos a implementar el codigo C de la función, le definimos los parametros y le creamos el cuerpo a la función. Aquí lo que vemos es una simple suma hecha en el lenguaje C.
## Crear librearías compartidas `.so`
Ahora que ya tenemos el codigo hecho lo que resta es crear las librerías para su posterior consumo en el codigo Java.

Creamos un archivo llamado `Android.mk` en la carpeta `jni` el cual tendrá las ordenes necesarias para la creación de las librerías.
Una vez hecho esto podemos proceder a crear las librerías.

El comando `ndk-build` realiza la tarea de construir las librerías para cada una de las arquitecturas, si lo deseamos podemos especificarle
que arquitecturas queremos pasandole el parametro `APP_ABI = x86` por ejemplo.
Sin embargo, otra forma de hacerlo es crear un archivo `Application.mk` (opcional) en la carpeta `jni` donde especifiquemos esto.

Aquí especificamos que queremos todas las arquitecturas.

La ejecución del anterior comando nos da como resultado las librerías para todas las arquitecturas en una carpeta llamada `libs`.
## Consumo de las librerías
Ahora procedemos con la parte mas sencilla, utilizar las librerías para ejecutar el codigo C en nuestro proyecto Android. Para esto debemos
renombrar la carpeta `libs` a `jniLibs` y despues agregar las siguientes lineas de codigo a nuestra clase `ClaseNativa.java`

El nombre debe ser el de la librería sin el prefijo `lib`y sin la extención `.so`
Y con todo esto ya podremos hacer uso de nuestra suma en C llamando a la funcion `ClaseNativa.sumar()`.
## Importación de las librerías en otro proyecto
Hasta este punto ya puede ejecutar codigo nativo en C en tu proyecto de android donde construiste la librería compartida. Pero te darás
cuenta que si tomas estas librerías `.so` y las incluyes en otro proyecto no te van a funcionar. La razón es que la función `sumar` de la librería está siendo exportada para una determinada clase de un paquete en específico, este paquete es el del proyecto en donde se construyó. Por lo tanto, para que funcione en otro proyecto debes renombrar las funciones y los archivos exportados por JNI, el nombre que debes colocarle es el del paquete de el del nuevo proyecto donde quieres correr la librería, veamos el proceso.
Vamos a suponer que el proyecto donde queremos usar la librería tiene el paquete `com.paquete.deprueba.importacion.libreria.libreria`, haremos lo siguiente.

Vamos a cambiar las partes resaltadas (en la imagen ya están cambiadas) por el nuevo paquete cambiando los puntos por guiones bajos.
En la imagen superior estamos ubicados en la cabecera.

Hacemos el mismo procedimiento en el archivo donde importamos la cabecera e implementamos el codigo C de la función.

La ultima parte donde debemos cambiarlo es en el archivo Android.mk para que construya las librerías partiendo de los archivos renombrados.
Y listo, lo que sigue es volver a construir las librerías utilizando el comando `ndk-build` tal como lo hicimos anteriormente.
## Usar codigo C++ e imprimir logs
Ahora lo que queremos es usar codigo C++ en vez de C, para eso simplemente renombramos nuestro archivo `.c` a `.cpp`, sin embargo, si
utilizamos importaciones como `#include ` vamos a notar el siguiente error.

Para solucionarlo agregamos la siguiente linea al archivo `Application.mk`

Una vez agregada esa linea, volvemos a construir la librería y no se presenta ningun problema.
Ahora procederemos a implementar codigo C++ y a agregar Logs para poder verlos en nuestra consola.
Para agregar logs incluimos la cabecera: `android/log.h` en nuestro codigo. Posteriormente agregamos la siguiente linea en `Android.mk`

Con esto agregado podemos utilizar la siguiente funcion para imprimir logs.

Si todo lo anterior está OK, el resultado será el siguiente

En la imagen de arriba podemos ver en el LogCat los logs que definimos en el codigo de C++