使用本征库和JNI一个简单的NDK项目 [英] A simple ndk project using the Eigen library and jni

查看:275
本文介绍了使用本征库和JNI一个简单的NDK项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以,今天从人们对这里的一些帮助,我放在一起使用NDK一个简单的Andr​​oid应用程序。我进口征库右转入我在源代码树创建,然后在利用cygwin我能够编译该项目的JNI文件夹。继承人的来源,以便其他人试图从学习C ++的数据传递来回java的JNI基础知识和背部有一些code通过去。该应用程序只需要在领域的EditText 6个号码,当用户点击按钮两条浮法数组被传递给本地方法和装成两本征浮法向量在那里,然后加在一起。两个向量的乘积被传递回java和然后在一个TextView显示。

继承人对征库链接Android的:

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

您只需要实际本征的文件夹是下一层中的文件树。只需复制和文件夹的本征这就是一层粘贴到本征源和地方,你创建握住你的C ++ code在你的Andr​​oid项目JNI的文件夹内。

继承人的java的:

 包jnimath.act;进口android.app.Activity;
进口android.os.Bundle;
进口android.view.View;
进口android.view.View.OnClickListener;
进口android.widget.Button;
进口android.widget.EditText;
进口android.widget.TextView;公共类JnimathActivity延伸活动{
 / **当第一次创建活动调用。 * /公众的EditText X;
公众的EditTextÿ;
公众的EditText Z者除外;公众的EditText X2;
公众的EditText Y2;
公众的EditText Z2;公众持股量[] vecArray;公众的TextView textView1;
公共按钮来运行;浮动[] = ARRAY3新的浮动[3];
浮动[]数组1 =新的浮动[3];
 浮动[]数组2 =新的浮动[3]; @覆盖
 公共无效的onCreate(捆绑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);
    运行=(按钮)findViewById(R.id.run)​​;    run.setOnClickListener(新OnClickListener(){        @覆盖
        公共无效的onClick(视图v){            数组1 [0] = Float.parseFloat(x.getText()的toString());
            数组1 [1] = Float.parseFloat(y.getText()的toString());
            数组1 [2] = Float.parseFloat(z.getText()的toString());            数组2 [0] = Float.parseFloat(x2.getText()的toString());
            数组2 [1] = Float.parseFloat(y2.getText()的toString());
            数组2 [2] = Float.parseFloat(z2.getText()的toString());
            ARRAY3 =测试(数组1,数组2);            字符串文本= ARRAY3 [0] ++ ARRAY3 [1] ++ ARRAY3 [2];
            textView1.setText(文本);        }    });}公众本机浮点[]测试(浮动[]数组1,浮法[]数组2);静态的 {
    的System.loadLibrary(测试);
}
}

和C ++的code:

 的#include<&iostream的GT;
#包括LT&;艾根/密>
#包括LT&;&math.h中GT;
#包括LT&;&jni.h GT;使用本征空间;Vector3f VEC;
Vector3f VEC2;
Vector3f vecRtrn;
无效vecLoad(浮法X,浮法Y,浮Z,浮X2,Y2浮动,浮动Z2){VEC(0)= X;
VEC(1)= Y;
VEC(2)= Z;
VEC2(0)= X 2;
VEC2(1)= Y2;
VEC2(2)= Z2; }无效vecAdd(Vector3f VECA,Vector3f vecB){
vecRtrn = VECA + vecB;
 }为externC
{
JNIEXPORT jfloatArray JNICALL Java_jnimath_act_JnimathActivity_test
(JNIEnv的* ENV,jobject OBJ,jfloatArray fltarray1,jfloatArray fltarray2)
{jfloatArray结果;
  结果= env-> NewFloatArray(3);
 如果(结果== NULL){
     返回NULL; / *总分抛出内存不足的错误* /
 }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);数组1 [0] = vecRtrn [0];
数组1 [1] = vecRtrn [1];
数组1 [2] = vecRtrn [2];env-> ReleaseFloatArrayElements(fltarray1,FLT1,0);
env-> ReleaseFloatArrayElements(fltarray2,FLT2,0);
env-> SetFloatArrayRegion(结果为0,3,数组1);
返回结果;}
}

现在继承人的Andr​​oid.mk文件:

  LOCAL_PATH:= $(叫我-DIR)
包括$(CLEAR_VARS)
LOCAL_MODULE:=测试
LOCAL_SRC_FILES:= TEST.CPP
包括$(BUILD_SHARED_LIBRARY)

刹那间还需要建立一个Application.mk这样你就可以使用STL使用本征:

  APP_STL:= stlport_static

最后但并非最不重要的是布局文件:

 <?XML版本=1.0编码=UTF-8&GT?;
< LinearLayout中的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
 机器人:layout_width =FILL_PARENT
 机器人:layout_height =FILL_PARENT
 机器人:方向=垂直><的TextView
    机器人:layout_width =FILL_PARENT
    机器人:layout_height =WRAP_CONTENT
    机器人:文字=@字符串/你好/><的EditText
    机器人:ID =@ + ID / X
    机器人:layout_width =match_parent
    机器人:layout_height =WRAP_CONTENT
    机器人:提示=Z>    < requestFocus的/>
< /&的EditText GT;<的EditText
    机器人:ID =@ + ID / Y
    机器人:layout_width =match_parent
    机器人:layout_height =WRAP_CONTENT
    机器人:提示=Y/><的EditText
    机器人:ID =@ + ID / Z
    机器人:layout_width =match_parent
    机器人:layout_height =WRAP_CONTENT
    机器人:提示=Z/><的EditText
    机器人:ID =@ + ID / X2
    机器人:layout_width =match_parent
    机器人:layout_height =WRAP_CONTENT
    机器人:提示=X2/><的EditText
    机器人:ID =@ + ID / Y2
    机器人:layout_width =match_parent
    机器人:layout_height =WRAP_CONTENT
    机器人:提示=Y 2/><的EditText
    机器人:ID =@ + ID / Z2
    机器人:layout_width =match_parent
    机器人:layout_height =WRAP_CONTENT
    机器人:提示=Z2/><按钮
    机器人:ID =@ + ID /运行
    机器人:layout_width =WRAP_CONTENT
    机器人:layout_height =WRAP_CONTENT
    机器人:文字=运行/><的TextView
    机器人:ID =@ + ID / textView1
    机器人:layout_width =WRAP_CONTENT
    机器人:layout_height =WRAP_CONTENT
    机器人:文字=矩阵输出/>< / LinearLayout中>

我实际使用cygwin的使用NDK-build命令,但你现在可以使用好老的Windows命令行做同样的事情。来吧,用这个作为样本,以了解如何从Java传递一些数据,以C ++使用NDK。肯定是一个严重缺乏对此事真的好文档。此外,如果你希望使用一个快速的本地数学库在此链接查看征:

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

我希望这东西可以帮助一些一出来像它帮助我学习如何从Java数据传递给本地侧面​​和背面:)


解决方案

因此​​,这是东西,让我开始能够从Java到C ++传递值来回但这里的NDK

HTTP://$c$c.google.com/p/ awesomeguy /维基/ JNITutorial

我拿起一堆东西从那里以及这本书

http://www.amazon.com/Android-Beginners-Guide-Sylvain-Ratabouil/ DP / 1849691525

So today with some help from the people on here I put together a simple android app that uses the ndk. I imported the eigen library right into the jni folder that I created in the source tree and then using cygwin I was able to compile the project. Heres the source so other people trying to learn jni basics passing data back and forth from c++ to java and back have some code to go by. The app just takes 6 numbers in edittext fields and when the user clicks the button two float arrays are passed to the native method and loaded into two eigen float vectors where they are then added together. The product of the two vectors is passed back to java and then displayed in a textview.

Heres a link to the eigen library for android:

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

You just need the actual eigen folder which is one layer down in the file tree. Just copy and paste the eigen folder thats one layer into the eigen source and place inside the jni folder that you create to hold your c++ code in your android project.

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

And the C++ code:

#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;

}
}

Now heres the Android.mk file:

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

Youll also need to set up an Application.mk so you can use the stl to use eigen:

APP_STL := stlport_static

Last but not least is the layout file:

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

I actually used cygwin to use the ndk-build command but you can now use the good old windows command line to do the same thing. Go ahead and use this as a sample to learn how to pass some data from java to c++ using the ndk. There definitely is a severe lack of really good documentation on the matter. Also if your looking to use a fast native math library check out eigen at this link:

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

I hope this stuff helps some one out like it helped me to learn how to pass data from java to the native side and back :)

解决方案

So this was something that got me started being able to pass values back and forth from java to c++ but here's a really great full fledged tutorial on the ndk

http://code.google.com/p/awesomeguy/wiki/JNITutorial

I picked up a bunch of stuff from there as well as this book

http://www.amazon.com/Android-Beginners-Guide-Sylvain-Ratabouil/dp/1849691525

这篇关于使用本征库和JNI一个简单的NDK项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆