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

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

问题描述

所以今天在这里的一些人的帮助下,我整理了一个使用 ndk 的简单 android 应用程序.我将 eigen 库直接导入到我在源代码树中创建的 jni 文件夹中,然后使用 cygwin 我能够编译该项目.这是源代码,因此其他试图学习 jni 基础知识的人将数据从 c++ 来回传递到 java 并返回一些代码.该应用程序仅在 edittext 字段中接收 6 个数字,当用户单击按钮时,两个浮点数组被传递给本机方法并加载到两个特征浮点向量中,然后将它们相加在一起.两个向量的乘积被传回java,然后显示在一个文本视图中.

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.

这是一个指向 android 特征库的链接:

Heres a link to the eigen library for android:

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

您只需要文件树中一层的实际特征文件夹.只需将一层的 eigen 文件夹复制并粘贴到 eigen 源代码中,然后放入您创建的 jni 文件夹中,以将您的 c++ 代码保存在您的 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.

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

还有 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;

}
}

现在是 Android.mk 文件:

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)

您还需要设置一个 Application.mk 以便您可以使用 stl 来使用 eigen:

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>

我实际上使用 cygwin 来使用 ndk-build 命令,但您现在可以使用旧的 Windows 命令行来做同样的事情.继续并以此为示例,学习如何使用 ndk 将一些数据从 java 传递到 c++.肯定严重缺乏关于此事的真正好的文件.此外,如果您希望使用快速的本地数学库,请在此链接中查看 eigen:

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

我希望这些东西可以帮助一些人,就像它帮助我学习如何将数据从 java 传递到本机端并返回:)

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 :)

推荐答案

所以这让我开始能够从 java 到 c++ 来回传递值,但这里有一个非常棒的关于 ndk 的完整教程

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-初学者-指南-Sylvain-Ratabouil/dp/1849691525

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

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