2011-12-17 5 views
21

Quindi oggi con un po 'di aiuto da parte delle persone qui ho messo insieme una semplice app per Android che usa il ndk. Ho importato la libreria eigen direttamente nella cartella jni che ho creato nell'albero dei sorgenti e quindi utilizzando cygwin I è stato possibile compilare il progetto. Ecco la fonte in modo che altre persone che cercano di imparare le basi jni passando i dati avanti e indietro da C++ a java e viceversa abbiano del codice da seguire. L'app prende solo 6 numeri nei campi di edittext e quando l'utente fa clic sul pulsante due array float vengono passati al metodo nativo e caricati in due vettori float eigen dove vengono quindi aggiunti insieme. Il prodotto dei due vettori viene passato a java e quindi visualizzato in una finestra di testo.Un semplice progetto ndk che utilizza la libreria Eigen e jni

Heres un link alla libreria Eigen per Android:

https://bitbucket.org/erublee/eigen-android 

Hai solo bisogno della cartella attuale eigen che è uno strato basso nella struttura di file. Basta copiare e incollare la cartella eigen che rappresenta un livello nella fonte eigen e posizionarla all'interno della cartella jni che si crea per contenere il codice C++ nel progetto Android.

Heres 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"); 
} 
} 

E il codice 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; 

} 
} 

Ora heres il file Android.mk:

LOCAL_PATH := $(call my-dir) 
include $(CLEAR_VARS) 
LOCAL_MODULE := test 
LOCAL_SRC_FILES := test.cpp 
include $(BUILD_SHARED_LIBRARY) 

Youll anche bisogno di creare un'applicazione .mk così puoi usare lo stl per usare eigen:

APP_STL := stlport_static 

Ultimo ma non meno importante è il file di layout:

<?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> 

Ho utilizzato Cygwin per usare il comando NDK-build, ma ora è possibile utilizzare il buon vecchio Windows riga di comando per fare la stessa cosa. Vai avanti e usalo come esempio per imparare come passare alcuni dati da Java a C++ usando il ndk. Sicuramente c'è una grave mancanza di documentazione davvero buona in merito. Anche se state cercando di utilizzare una libreria matematica nativa Check out Eigen a questo link:

http://eigen.tuxfamily.org/index.php?title=Main_Page 

Spero che questa roba aiuta qualcuno fuori come mi ha aiutato a imparare come passare i dati da Java a lato nativa e indietro :)

+1

che era disponibile! grazie – user8709

+0

Nessun problema :) Mi ci sono voluti due giorni solo per capire come ottenere i dati da e verso il modo in cui ne avevo bisogno utilizzando JNI, quindi ho pensato che avrebbe aiutato le altre persone a vedere come funzionava. –

+1

pubblica qualcosa come risposta e accetta! ;) – n00b

risposta

Problemi correlati