{"id":24064694,"url":"https://github.com/crissalvarezh/addcodigocenandroid","last_synced_at":"2026-04-13T03:39:00.083Z","repository":{"id":108747070,"uuid":"200867768","full_name":"CrissAlvarezH/AddCodigoCEnAndroid","owner":"CrissAlvarezH","description":"Proyecto de ejemplo para integrar código nativo en C en Android.","archived":false,"fork":false,"pushed_at":"2019-08-20T16:35:11.000Z","size":6231,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-09T23:03:31.913Z","etag":null,"topics":["android","c","cpp","java","jni","jni-android","ndk"],"latest_commit_sha":null,"homepage":"","language":"Makefile","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/CrissAlvarezH.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2019-08-06T14:27:49.000Z","updated_at":"2019-08-20T20:08:56.000Z","dependencies_parsed_at":"2023-06-04T16:45:15.055Z","dependency_job_id":null,"html_url":"https://github.com/CrissAlvarezH/AddCodigoCEnAndroid","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/CrissAlvarezH/AddCodigoCEnAndroid","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CrissAlvarezH%2FAddCodigoCEnAndroid","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CrissAlvarezH%2FAddCodigoCEnAndroid/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CrissAlvarezH%2FAddCodigoCEnAndroid/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CrissAlvarezH%2FAddCodigoCEnAndroid/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CrissAlvarezH","download_url":"https://codeload.github.com/CrissAlvarezH/AddCodigoCEnAndroid/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CrissAlvarezH%2FAddCodigoCEnAndroid/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265965972,"owners_count":23857055,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","c","cpp","java","jni","jni-android","ndk"],"created_at":"2025-01-09T10:39:45.006Z","updated_at":"2026-04-13T03:38:54.893Z","avatar_url":"https://github.com/CrissAlvarezH.png","language":"Makefile","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Descripción\nEste proyecto se creó a modo de ejemplo para integrar codigo C/C++ en un proyecto de Android utilizando JNI y NDK.\nA continuación están los pasos a seguir para lograr este integración.\n\n# Demostración\nLa 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\nsuma está hecha en el lenguaje C.\n\n![Demo](https://github.com/CrissAlvarezH/ImagenesRepos/blob/master/imgs/AddCodigoCEnAndroid/demo.gif)\n\n# Guía\n\nEsta guía está separada en varias partes, la integración de codigo C en el cual\nmuestro 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\nagregaremos logs para verlos en el LogCat de Android Studio.\n\n## Integración con codigo C\n\n\u003cimg alt=\"Clase con metodo navite\"  src=\"https://github.com/CrissAlvarezH/ImagenesRepos/blob/master/imgs/AddCodigoCEnAndroid/clase_nativa.png\" /\u003e\n\nEmpezamos creando una clase en Java que contendrá los metodos que se escribirán en C. Como puedes notar utilizamos la palabra reservada\n`native` para declarar el metodo, tambien puedes notar que no tiene cuerpo, esto es porque el cuerpo se lo definiremos en C.\n\n\u003c/br\u003e\n\n\u003cimg alt=\"Compilar clase nativa\" src=\"https://github.com/CrissAlvarezH/ImagenesRepos/blob/master/imgs/AddCodigoCEnAndroid/compilar_clase_nativa.png\" /\u003e\n\nCompilamos la clase que acabamos de crear utilizando `javac`, esto nos dará como resultado un `.class` \n\n\u003c/br\u003e\n\n\u003cimg alt=\"Crear cabecera\" src=\"https://github.com/CrissAlvarezH/ImagenesRepos/blob/master/imgs/AddCodigoCEnAndroid/crear_cabecera_de_java.png\" /\u003e\n\nAhora creamos el fichero de cabecera JNI para dicha clase, esto lo hacemos con el comando \u003c/br\u003e\n`javah -c java \u003cnombre del paquete\u003e.\u003cnombre de la clase\u003e`, posteriormente\ncreamos un directorio llamado `jni` y movemos nuestro `.h`, recién creado, dentro.\n\n\u003cimg alt=\"Cabecera\" src=\"https://github.com/CrissAlvarezH/ImagenesRepos/blob/master/imgs/AddCodigoCEnAndroid/cabecera_clase_nativa.png\" /\u003e\n\nAl abrir el archivo podemos ver que contiene la función que hemos declarado en `ClaseNativa.java`, pero su nombre tiene la siguiente estructura\n`Java_\u003cnombre del paquete separado por guión bajo\u003e_\u003cnombre de la clase\u003e_\u003cnombre de la función\u003e`.\n\n\u003c/br\u003e\n\n\u003cimg alt=\"Crear c\" src=\"https://github.com/CrissAlvarezH/ImagenesRepos/blob/master/imgs/AddCodigoCEnAndroid/crear_c_copiado_de_cabecera.png\" /\u003e\n\nAhora 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 \nextención de `.h` a `.c` y le hacemos los siguientes cambios\n\n\u003c/br\u003e\n\n\u003cimg alt=\"Codigo c jni\" src=\"https://github.com/CrissAlvarezH/ImagenesRepos/blob/master/imgs/AddCodigoCEnAndroid/codigo_c_con_jni.png\" /\u003e\n\nEn 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.\n\n\u003c/br\u003e\n\n## Crear librearías compartidas `.so`\n\nAhora que ya tenemos el codigo hecho lo que resta es crear las librerías para su posterior consumo en el codigo Java.\n\n\u003c/br\u003e\n\n\u003cimg alt=\"Android mk\" src=\"https://github.com/CrissAlvarezH/ImagenesRepos/blob/master/imgs/AddCodigoCEnAndroid/archivo_android_mk.png\" /\u003e\n\nCreamos un archivo llamado `Android.mk` en la carpeta `jni` el cual tendrá las ordenes necesarias para la creación de las librerías.\nUna vez hecho esto podemos proceder a crear las librerías.\n\n\u003c/br\u003e\n\n\u003cimg alt=\"Comando ndk-build\" src=\"https://github.com/CrissAlvarezH/ImagenesRepos/blob/master/imgs/AddCodigoCEnAndroid/comando_ndk-build.png\" /\u003e\n\nEl comando `ndk-build` realiza la tarea de construir las librerías para cada una de las arquitecturas, si lo deseamos podemos especificarle\nque arquitecturas queremos pasandole el parametro `APP_ABI = x86` por ejemplo.\nSin embargo, otra forma de hacerlo es crear un archivo `Application.mk` (opcional) en la carpeta `jni` donde especifiquemos esto.\n\n\u003c/br\u003e\n\n\u003cimg alt=\"Application mk\" src=\"https://github.com/CrissAlvarezH/ImagenesRepos/blob/master/imgs/AddCodigoCEnAndroid/archivo_application_mk.png\" /\u003e\n\nAquí especificamos que queremos todas las arquitecturas.\n\n\u003c/br\u003e\n\n\u003cimg alt=\"Librerías compiladas\" src=\"https://github.com/CrissAlvarezH/ImagenesRepos/blob/master/imgs/AddCodigoCEnAndroid/librerias_compiladas.png\" /\u003e\n\nLa ejecución del anterior comando nos da como resultado las librerías para todas las arquitecturas en una carpeta llamada `libs`.\n\n## Consumo de las librerías\n\nAhora procedemos con la parte mas sencilla, utilizar las librerías para ejecutar el codigo C en nuestro proyecto Android. Para esto debemos\nrenombrar la carpeta `libs` a `jniLibs` y despues agregar las siguientes lineas de codigo a nuestra clase `ClaseNativa.java`\n\n\u003cimg alt=\"Librerías compiladas\" src=\"https://github.com/CrissAlvarezH/ImagenesRepos/blob/master/imgs/AddCodigoCEnAndroid/clase_nativa_loadlibrary.png\" /\u003e\n\nEl nombre debe ser el de la librería sin el prefijo `lib`y sin la extención `.so`\n\nY con todo esto ya podremos hacer uso de nuestra suma en C llamando a la funcion `ClaseNativa.sumar()`.\n\n## Importación de las librerías en otro proyecto\n\nHasta este punto ya puede ejecutar codigo nativo en C en tu proyecto de android donde construiste la librería compartida. Pero te darás\ncuenta 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.\n\n\u003c/br\u003e\n\nVamos a suponer que el proyecto donde queremos usar la librería tiene el paquete `com.paquete.deprueba.importacion.libreria.libreria`, haremos lo siguiente.\n\n\u003cimg alt=\"Librerías compiladas\" src=\"https://github.com/CrissAlvarezH/ImagenesRepos/blob/master/imgs/AddCodigoCEnAndroid/nombre_de_paquete_camiado.png\" /\u003e\n\nVamos a cambiar las partes resaltadas (en la imagen ya están cambiadas) por el nuevo paquete cambiando los puntos por guiones bajos.\nEn la imagen superior estamos ubicados en la cabecera.\n\n\u003c/br\u003e\n\n\u003cimg alt=\"Librerías compiladas\" src=\"https://github.com/CrissAlvarezH/ImagenesRepos/blob/master/imgs/AddCodigoCEnAndroid/nombre_paquete_cambiado_en_el_c.png\" /\u003e\n\nHacemos el mismo procedimiento en el archivo donde importamos la cabecera e implementamos el codigo C de la función.\n\n\u003c/br\u003e\n\n\u003cimg alt=\"Librerías compiladas\" src=\"https://github.com/CrissAlvarezH/ImagenesRepos/blob/master/imgs/AddCodigoCEnAndroid/nombre_paquete_cambiado_en_androidmk.png\" /\u003e\n\nLa ultima parte donde debemos cambiarlo es en el archivo Android.mk para que construya las librerías partiendo de los archivos renombrados. \n\nY listo, lo que sigue es volver a construir las librerías utilizando el comando `ndk-build` tal como lo hicimos anteriormente.\n\n## Usar codigo C++ e imprimir logs \n\nAhora lo que queremos es usar codigo C++ en vez de C, para eso simplemente renombramos nuestro archivo `.c` a `.cpp`, sin embargo, si \nutilizamos importaciones como `#include \u003cstring\u003e` vamos a notar el siguiente error.\n\n\u003cimg alt=\"Librerías compiladas\" src=\"https://github.com/CrissAlvarezH/ImagenesRepos/blob/master/imgs/AddCodigoCEnAndroid/error_incluir_string_cpp.png\" /\u003e\n\n\u003c/br\u003e\n\nPara solucionarlo agregamos la siguiente linea al archivo `Application.mk`\n\n\u003cimg alt=\"Librerías compiladas\" src=\"https://github.com/CrissAlvarezH/ImagenesRepos/blob/master/imgs/AddCodigoCEnAndroid/add_soporte_cpp_applicationmk.png\" /\u003e\n\n\u003c/br\u003e\n\nUna vez agregada esa linea, volvemos a construir la librería y no se presenta ningun problema.\nAhora procederemos a implementar codigo C++ y a agregar Logs para poder verlos en nuestra consola.\nPara agregar logs incluimos la cabecera: `android/log.h` en nuestro codigo. Posteriormente agregamos la siguiente linea en `Android.mk`\n\n\u003cimg alt=\"Librerías compiladas\" src=\"https://github.com/CrissAlvarezH/ImagenesRepos/blob/master/imgs/AddCodigoCEnAndroid/add_lib_para_logs_androidmk.png\" /\u003e\n\n\u003c/br\u003e\n\nCon esto agregado podemos utilizar la siguiente funcion para imprimir logs.\n\n\u003cimg alt=\"Librerías compiladas\" src=\"https://github.com/CrissAlvarezH/ImagenesRepos/blob/master/imgs/AddCodigoCEnAndroid/logs_android_en_cpp.png\" /\u003e\n\n\u003c/br\u003e\n\nSi todo lo anterior está OK, el resultado será el siguiente\n\n\u003cimg alt=\"Librerías compiladas\" src=\"https://github.com/CrissAlvarezH/ImagenesRepos/blob/master/imgs/AddCodigoCEnAndroid/log_cpp.png\" /\u003e\n\nEn la imagen de arriba podemos ver en el LogCat los logs que definimos en el codigo de C++\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcrissalvarezh%2Faddcodigocenandroid","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcrissalvarezh%2Faddcodigocenandroid","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcrissalvarezh%2Faddcodigocenandroid/lists"}