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 包装器,并将 JNI 方法添加到 c++ 文件中。代码如下:

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 端的类和一组 JNI C 调用来访问、修改和调用 Java 对象上的方法。Java 端的 JNI 本机方法对您没有用处,因为它可以采用(输入或输出)的唯一参数也只能是 Java 对象(或原语或数组)。根本没有办法将 C(++) 结构/对象传递给 Java 端。

于 2012-12-13T21:57:38.570 回答
0

您可以根据需要使用 C 代码进行操作并通过 JNI 传递\返回值,您可以在 androidndk/samples - helloJni 中找到 JNI 示例。

例如:

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 回答
0

正如我在第二次更新中所说,SWIG非常适合我的需求。

于 2013-05-10T10:13:45.680 回答