7

私は Android NDK の基本を学ぼうとしていますが、C++ クラスでそれを使用しなければならないときに立ち往生しています。

単純な関数で使用する方法は理解していますが、C++ クラスのフィールドとメソッドを操作できるようにするにはどうすればよいですか?

私はこの単純な C++ クラスでそれをやろうとしています:

#include <cstdlib>
#include <jni.h>
using namespace std;


class Point {
   int x, y; // coordonnées du point

   public:
      Point() {
         this->x = 0;
         this->y = 0;
      }

      Point(int x, int y) {
         this->x = x;
         this->y = y;
      }

      int getX() const {
         return x;
      }

      int getY() const {
         return y;
      }

      Point symetrique() const {
         return Point(-x, -y);
      }

      bool operator ==(const Point &p) const {
         return this->x == p.getX() && this->y == p.getY();
      }
};

extern "C" {
    JNIEXPORT jlong JNICALL Java_com_example_jnipoint_JPoint_createPoint__
      (JNIEnv *, jobject);

    JNIEXPORT jlong JNICALL Java_com_example_jnipoint_JPoint_createPoint__II
      (JNIEnv *, jobject, jint, jint);

    JNIEXPORT jint JNICALL Java_com_example_jnipoint_JPoint_nativeGetX
      (JNIEnv *, jobject, jlong);

    JNIEXPORT jint JNICALL Java_com_example_jnipoint_JPoint_nativeGetY
      (JNIEnv *, jobject, jlong);

    JNIEXPORT jlong JNICALL Java_com_example_jnipoint_JPoint_nativeSymetrique
      (JNIEnv *, jobject, jlong);
};


JNIEXPORT jlong JNICALL Java_com_example_jnipoint_JPoint_createPoint__(JNIEnv* env, jobject thiz) {
    return (jlong)(new Point());
}

JNIEXPORT jlong JNICALL Java_com_example_jnipoint_JPoint_createPoint__II(JNIEnv* env, jobject thiz, jint x, jint y) {
    return (jlong)(new Point(x, y));
}

JNIEXPORT jint JNICALL Java_com_example_jnipoint_JPoint_nativeGetX(JNIEnv* env, jobject thiz, jlong nativePointer) {
    return ((Point*)nativePointer)->getX();
}

JNIEXPORT jint JNICALL Java_com_example_jnipoint_JPoint_nativeGetY(JNIEnv* env, jobject thiz, jlong nativePointer) {
    return ((Point*)nativePointer)->getY();
}

jlong Java_com_example_jnipoint_JPoint_nativeSymetrique(JNIEnv* env, jobject thiz, jlong nativePointer) {
    return ((Point*)nativePointer)->symetrique();
}

サンプルを見つけようとしましたが、これまでのところ何もありません... 適切なキーワードを使用していない可能性があります

*更新*

c++ Point クラスの Java ラッパーを作成し、c++ ファイルに JNI メソッドを追加しました。コードは次のとおりです。

public class JPoint {

    private long nativePointer;

    public JPoint() {
        nativePointer = createPoint();
    }

    public JPoint(int x, int y) {
        nativePointer = createPoint(x, y);
    }

    public int getX() {
        return nativeGetX(nativePointer);
    }

    public int getY() {
        return nativeGetY(nativePointer);
    }

    public JPoint symetrique() {
        JPoint tmp = new JPoint();
        tmp.nativePointer = nativeSymetrique(nativePointer);
        return tmp;
    }

    // TODO
    /*public boolean equals(Object o) {
        return nativeEquals(o);
    }*/

    private native long createPoint(); // Void constructor
    private native long createPoint(int x, int y);
    private native int nativeGetX(long nativePointer);
    private native int nativeGetY(long nativePointer);
    private native long nativeSymetrique(long nativePointer);
    //private native boolean nativeEquals(Object p); TODO
}

現在、nativeSymetrique 関数に行き詰まっています。'Point' を 'jlong​​' に変換できないと表示されています。誰でもこれについて私を助けることができますか? ありがとう

* 更新 2 *

SWIG は私の問題を解決しました。ラッパーを手書きする必要はありません。大きなライブラリには良い選択のようです。

4

3 に答える 3

1

JNAをご覧ください。

JNIは、CからJavaクラス/オブジェクトにアクセスすることを目的としています。つまり、JNIはJVMにアクセスするためのC関数を提供します。ただし、その逆はありません。JVMからC構造体(C ++クラス)にアクセスする方法です。Javaにはそのようなメソッドはありません。したがって、C ++とJavaの間に「クラスリフレクション」が必要な場合は、Java側にクラスを配置し、Javaオブジェクトのメソッドにアクセス、変更、および呼び出すための一連のJNIC呼び出しを実行するだけです。Java側のJNIネイティブメソッドは役に立ちません。これは、JNIが取ることができる(入力または出力する)パラメーターは、Javaオブジェクト(またはプリミティブまたは配列)のみであるためです。C(++)構造体/オブジェクトをJava側に渡す方法はありません。

于 2012-12-13T21:57:38.570 に答える
0

2 回目の更新で述べたように、SWIGは私のニーズにぴったりでした。

于 2013-05-10T10:13:45.680 に答える
0

必要に応じて C コードを操作し、JNI 経由で値を返すことができます。JNI サンプルは androidndk/samples - helloJni にあります。

例えば:

JNIEXPORT jfloat JNICALL Java_com_opengl_glworld_GLWorldRenderer_changeCurrentArea(JNIEnv *env, jobject obj, jfloat curArea)
{
    area = curArea;
    return area;
    // here you can execude you C code, you can access to methods of class,
    // or method  that use your classes.
}
于 2012-12-13T14:30:39.203 に答える