android - studio - Un proyecto ndk simple usando la biblioteca Eigen y jni
android ndk location (1)
Así que esto fue algo que me permitió empezar a pasar valores de java a c ++, pero aquí hay un tutorial muy completo sobre el ndk
http://code.google.com/p/awesomeguy/wiki/JNITutorial
Recogí un montón de cosas de allí, así como este libro
http://www.amazon.com/Android-Beginners-Guide-Sylvain-Ratabouil/dp/1849691525
Así que hoy, con la ayuda de la gente de aquí, armé una sencilla aplicación de Android que usa el ndk. Importé la biblioteca eigen directamente en la carpeta jni que creé en el árbol fuente y luego, usando cygwin, pude compilar el proyecto. Aquí está la fuente para que otras personas que intentan aprender jni básicos que pasan datos de C ++ a Java y viceversa tengan algún código para usar. La aplicación solo toma 6 números en los campos de texto de edición y cuando el usuario hace clic en el botón, dos matrices flotantes se pasan al método nativo y se cargan en dos vectores flotantes propios donde luego se suman. El producto de los dos vectores se devuelve a Java y luego se muestra en una vista de texto.
Aquí hay un enlace a la biblioteca eigen para Android:
https://bitbucket.org/erublee/eigen-android
Solo necesita la carpeta propia eigen, que está una capa hacia abajo en el árbol de archivos. Simplemente copie y pegue la carpeta eigen que es una capa en la fuente propia y colóquela dentro de la carpeta jni que crea para contener su código c ++ en su proyecto de Android.
Aquí está el java:
package jnimath.act;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class JnimathActivity extends Activity {
/** Called when the activity is first created. */
public EditText x;
public EditText y;
public EditText z;
public EditText x2;
public EditText y2;
public EditText z2;
public float[] vecArray;
public TextView textView1;
public Button run;
float[] array3 = new float[3];
float[] array1 = new float[3];
float[] array2 = new float[3];
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
x = (EditText)findViewById(R.id.x);
y = (EditText)findViewById(R.id.y);
z = (EditText)findViewById(R.id.z);
x2 = (EditText)findViewById(R.id.x);
y2 = (EditText)findViewById(R.id.y);
z2 = (EditText)findViewById(R.id.z);
textView1 = (TextView)findViewById(R.id.textView1);
run = (Button)findViewById(R.id.run);
run.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
array1[0] = Float.parseFloat(x.getText().toString());
array1[1] = Float.parseFloat(y.getText().toString());
array1[2] = Float.parseFloat(z.getText().toString());
array2[0] = Float.parseFloat(x2.getText().toString());
array2[1] = Float.parseFloat(y2.getText().toString());
array2[2] = Float.parseFloat(z2.getText().toString());
array3 = test(array1, array2);
String text = array3[0]+" "+array3[1]+" "+array3[2];
textView1.setText(text);
}
});
}
public native float[] test(float[] array1, float[] array2);
static {
System.loadLibrary("test");
}
}
Y el código de C ++:
#include <iostream>
#include <Eigen/Dense>
#include <math.h>
#include <jni.h>
using namespace Eigen;
Vector3f vec;
Vector3f vec2;
Vector3f vecRtrn;
void vecLoad(float x, float y, float z, float x2, float y2, float z2){
vec(0) = x;
vec(1) = y;
vec(2) = z;
vec2(0) = x2;
vec2(1) = y2;
vec2(2) = z2;
}
void vecAdd(Vector3f vecA, Vector3f vecB){
vecRtrn = vecA + vecB;
}
extern "C"
{
JNIEXPORT jfloatArray JNICALL Java_jnimath_act_JnimathActivity_test
(JNIEnv *env, jobject obj, jfloatArray fltarray1, jfloatArray fltarray2)
{
jfloatArray result;
result = env->NewFloatArray(3);
if (result == NULL) {
return NULL; /* out of memory error thrown */
}
jfloat array1[3];
jfloat* flt1 = env->GetFloatArrayElements( fltarray1,0);
jfloat* flt2 = env->GetFloatArrayElements( fltarray2,0);
vecLoad(flt1[0], flt1[1], flt1[2], flt2[0], flt2[1], flt2[2]);
vecAdd(vec, vec2);
array1[0] = vecRtrn[0];
array1[1] = vecRtrn[1];
array1[2] = vecRtrn[2];
env->ReleaseFloatArrayElements(fltarray1, flt1, 0);
env->ReleaseFloatArrayElements(fltarray2, flt2, 0);
env->SetFloatArrayRegion(result, 0, 3, array1);
return result;
}
}
Ahora aquí está el archivo Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := test
LOCAL_SRC_FILES := test.cpp
include $(BUILD_SHARED_LIBRARY)
También necesitará configurar un Application.mk para que pueda usar el stl para usar eigen:
APP_STL := stlport_static
Por último, pero no menos importante es el archivo de diseño:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />
<EditText
android:id="@+id/x"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="z" >
<requestFocus />
</EditText>
<EditText
android:id="@+id/y"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="y" />
<EditText
android:id="@+id/z"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="z" />
<EditText
android:id="@+id/x2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="x2" />
<EditText
android:id="@+id/y2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="y2" />
<EditText
android:id="@+id/z2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="z2" />
<Button
android:id="@+id/run"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="run" />
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="matrix output" />
</LinearLayout>
De hecho, utilicé cygwin para usar el comando ndk-build, pero ahora puede usar la buena línea de comandos de Windows para hacer lo mismo. Siga adelante y use esto como muestra para aprender a pasar algunos datos de Java a C ++ usando el ndk. Definitivamente hay una gran falta de documentación realmente buena sobre el tema. Además, si buscas utilizar una biblioteca de matemáticas nativa rápida echa un vistazo a eigen en este enlace:
http://eigen.tuxfamily.org/index.php?title=Main_Page
Espero que esto ayude a alguien que me haya ayudado a aprender cómo pasar datos de Java al lado nativo y viceversa :)