7

I'm trying to learn the basics of Android NDK but I'm stucked when I have to use it with a c++ class.

I understand how to use it with a simple function but what should I do to be able to manipulate the fields and the methods of a c++ class ?

I'm trying to do it with this simple c++ class :

#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();
}

I tried to find samples but nothing so far... Maybe I'm not using the right keywords

* UPDATE *

I created a Java wrapper for the c++ Point class and added to the c++ file JNI methods. The code is the following :

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
}

Right now I'm stucked with the nativeSymetrique function, it says that I cannot convert 'Point' to 'jlong'. Can anyone help me on this ? Thanks

* UPDATE 2 *

SWIG solved my issues, you don't have to handwrite the wrappers and it seems to be a good choice for big libraries.

Fr4nz
  • 1,616
  • 6
  • 24
  • 33
  • good question, if you can use something from "main()" than you can also write some functions in main that will call functions of class , it's very bad way but maybe it'll help you :) – Hayk Nahapetyan Dec 13 '12 at 14:23
  • do you use JNI? Where is JNI wrapper in your code? – dilix Dec 13 '12 at 14:25
  • Yes I plan to use JNI but this code is just a simple c++ class. I wonder where and how I should put JNI with that code – Fr4nz Dec 13 '12 at 14:46

3 Answers3

1

Have a look at JNA.

JNI is meant to access Java classes/objects from C. Which means that JNI gives you C functions for accessing JVM. But there is no way vice versa: to access C structures (C++ classes) from JVM. Java has no such methods. So if you want to have a "class reflection" between C++ and Java, the only you can do is to have the class on Java side and a set of JNI C calls to access, modify and call methods on the Java object. JNI native methods on Java side are of no use for you, because the only parameters it can take (in or out) can be again only Java objects (or primitives or arrays). There is simply no way to pass C(++) structures/objects to Java side.

Pavel Zdenek
  • 7,146
  • 1
  • 23
  • 38
  • Thanks for the answer, I'll have a look at JNA – Fr4nz Dec 14 '12 at 01:23
  • According to this post http://stackoverflow.com/questions/1556421/use-jni-instead-of-jna-to-call-native-code JNA is not good for my use because of c++ – Fr4nz Dec 16 '12 at 17:07
  • JNA is the nearest you can get to accessing native objects from Java. JNI does not provide anything at all, neither does Java in itself. So if JNA is unusable for you, then the second paragraph, and specifically the last sentence of it, is my answer. – Pavel Zdenek Dec 17 '12 at 09:30
0

You can manipulate with your C code as you wish and pass\return values via JNI, you can find JNI samples in androidndk/samples - helloJni.

For example:

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.
}
dilix
  • 3,761
  • 3
  • 31
  • 55
  • I know I have to use JNI, I read those samples but what about c++ classes and JNI ? You're saying that I'll have to write a JNI function for each methods of my Point class ? And I'll have to create a similar class (Point) on the Java side with native method ? – Fr4nz Dec 13 '12 at 14:44
  • Do you want to pass objects from java to c++? Check this answer http://stackoverflow.com/questions/4468276/how-to-pass-java-class-instance-as-a-parameter-to-jni-method and google can help with with passing objecs in JNI =) – dilix Dec 13 '12 at 14:51
  • http://stackoverflow.com/questions/2504334/passing-data-types-from-java-to-c-or-vice-versa-using-jni – dilix Dec 18 '12 at 14:38
0

As I said in my second update, SWIG was the perfect match for my needs.

Community
  • 1
  • 1
Fr4nz
  • 1,616
  • 6
  • 24
  • 33