El principal problema del uso de las librerías OpenCv para nuestro
proyecto fue el hecho de que éstas vienen escritas para el lenguaje orientado a
objetos c++, y no para Java.
Sin embargo, el entorno de desarrollo de Oracle permite la importación
de bibliotecas escritas en c++ mediante el llamado JNI (Java Native Interface).
Mediante éste método, y siguiendo los pasos desritos adelante, se pueden
importar en cualquier archivo escrito en java bibliotecas escritas en c/c++, de
igual manera que si éstas estuvieran escritas en java, pudiendo hacer uso de
objetos, métodos, etc.
Para la consecución de lo comentado anteriormente, se necesitó,
evidentemente, guardar en un directorio todas aquellos ficheros en c/c++ que
queramos incluir en nuestro código Java. Fue necesario que se guardaran de la
siguiente manera:
NombreDelFichero_jni.cpp
Después de ello, se procedió a su preparación para incluirlas en el
código Java. Para ello una pieza fundamental fueron los ficheros .mk. Dichos
ficheros deben estar incluidos en el directorio (que de ahora en adelante
llamaremos jni) en el que se encontraban los ficheros escritos en código
nativo. En dichos ficheros fue necesario incluir el siguiente código:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
#OPENCV_CAMERA_MODULES:=off
#OPENCV_INSTALL_MODULES:=off
#OPENCV_LIB_TYPE:=SHARED
include ../../sdk/native/jni/OpenCV.mk
LOCAL_SRC_FILES := <NombreDelFichero_jni.cpp>
LOCAL_C_INCLUDES += $(LOCAL_PATH)
LOCAL_LDLIBS += -llog -ldl
LOCAL_MODULE := <Nombre_Del_Fichero>
include $(BUILD_SHARED_LIBRARY)
En los que sustituyó lo encerrado por llaves por los ficheros que
deseamos convertir a biblioteas listas para usar en Java.
Una vez hecho esto, fue necesario hacer el "build" de ellas
para poder incluirlas en Java. Dicho proceso lo realiza el ndk-build. El
fichero se encuentra en el NDK que se instalaró anteriormente, directamente en
el Path principal. Para su uso, y dado que es un fichero Linux, se hizo uso de
la herramienta Cygwin.
Cygwin es una herramienta para Windows que permite usar la BashShell (y
otra Shell cualquiera) típica de UNIX en un entorno Windows. Puede obtenerse
directamente desde:
Una vez descargado, procedimos a su instalación. Por defecto, nos
instalará únicamente aquellas funcionalidades descritas como
"default". Sin embargo, dado que en nuestro caso necesitaremos hacer
un build de un código escrito en c/c++,
descargamos también todo lo relacionado con el apartado Dev (de
development). Allí encontramos compiladores de c++ que utilizamos para compilar
el código.
Una vez instalado y funcionando, escribimos en línea de comandos:
cd <path del jni>
para situarnos en donde tenemos el código escrito en c++.
Una vez allí, debimos encontrar y ejecutar directamente el ndk-build que
encontramos en el path del ndk. En nuestro caso, éste se encontraba en:
C:\Development\android-ndk-r8d-windows\android-ndk-r8d\ndk-build
Una vez hecho esto, es muy común que nos aparezca el siguiente error:
<Path del ndk>/build/gmsl/__gmsl:512: *** non-numeric
second argument to `wordlist' function: ''. Stop.
Esto es debido a una configuración no estandarizada del ndk-build. Para
ello debimos hacer lo siguiente:
Buscamos en el path indicado el fichero llamado __gmsl. Allí, en la
línea 512, donde se encuentra la función que nos da error con el segundo
argumento, teníamos:
int_encode = $(__gmsl_tr1)$(wordlist 1, $1,$(__gmsl_input_int))
Como nos daba un error por ser éste segundo argumento no numérico,
hicimos lo siguiente:
Cambiamos la declaración de la función por:
int_encode = $(__gmsl_tr1)$(wordlist 1,$(words $1),$
(__gmsl_input_int))
Guardamos el fichero y volvimos a ejecutar el ndk-build.
Una vez hecho esto, funcionó correctamente.
Así, con todo realizado correctamente, solo hizo falta cargar las
librerías generadas en la carpeta "libs"
Para ello, dentro de nuestro código Java, solo faltaba cargar la
librería con el Nombre que escogimos (sin el _jni). Para ello, escribimos:
static{
System.loadLibrary("Nombrede la librería");
}
y, más adelante en el código, declarar como nativos todos los métodos
que vamos a usar:
private native double NombreMetodo(args)
No hay comentarios:
Publicar un comentario