2011-12-17 30 views
21

Vì vậy, hôm nay với một số trợ giúp từ những người ở đây tôi kết hợp một ứng dụng Android đơn giản sử dụng ndk. Tôi đã nhập thư viện eigen vào thư mục jni mà tôi đã tạo trong cây nguồn và sau đó sử dụng Cygwin, tôi đã có thể biên dịch dự án. Heres nguồn để những người khác cố gắng để tìm hiểu cơ bản jni đi qua dữ liệu qua lại từ c + + để java và trở lại có một số mã để đi theo. Ứng dụng này chỉ mất 6 con số trong các trường edittext và khi người dùng nhấp vào nút, hai mảng phao được chuyển tới phương thức gốc và được nạp vào hai vectơ float riêng biệt, nơi chúng được thêm vào cùng nhau. Sản phẩm của hai vectơ được truyền lại cho java và sau đó được hiển thị trong chế độ xem văn bản.Một dự án ndk đơn giản bằng cách sử dụng thư viện Eigen và jni

Heres một liên kết đến các thư viện eigen cho android:

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

Bạn chỉ cần vào thư mục eigen thực tế đó là một lớp xuống trong cây tập tin. Chỉ cần sao chép và dán thư mục riêng mà một lớp vào nguồn riêng và đặt bên trong thư mục jni mà bạn tạo để giữ mã C++ trong dự án Android của bạn.

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

Và ++ mã 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; 

} 
} 

Bây giờ heres file Android.mk:

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

Youll cũng cần phải thiết lập một ứng dụng .mk để bạn có thể sử dụng stl để sử dụng eigen:

APP_STL := stlport_static 

Cuối cùng nhưng không kém phần quan là file 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> 

Tôi thực sự sử dụng Cygwin để sử dụng ndk-build lệnh nhưng bây giờ bạn có thể sử dụng cửa sổ dòng lệnh cũ tốt để làm điều tương tự. Hãy tiếp tục và sử dụng điều này làm mẫu để tìm hiểu cách chuyển một số dữ liệu từ java sang C++ bằng cách sử dụng ndk. Chắc chắn là thiếu tài liệu thực sự tốt về vấn đề này. Ngoài ra nếu tìm bạn để sử dụng một thư viện toán học gốc nhanh chóng kiểm tra eigen tại liên kết này:

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

Tôi hy vọng công cụ này sẽ giúp một số một ra như nó đã giúp tôi để tìm hiểu làm thế nào để truyền dữ liệu từ java sang phía mẹ đẻ và trở lại :)

+1

Điều đó rất hữu ích! Cảm ơn – user8709

+0

Đừng lo lắng :) Tôi mất hai ngày để tìm ra cách lấy dữ liệu qua lại theo cách tôi cần nó bằng JNI vì vậy tôi nghĩ nó sẽ giúp những người khác thấy tôi làm việc như thế nào. –

+1

đăng nội dung nào đó làm câu trả lời và chấp nhận! ;) – n00b

Trả lời

Các vấn đề liên quan