Search code examples
javac++arraysjava-native-interface

JNI First value of jintArray incorrect


What I'm trying to do is drawing a polygon from Java to a direct 2d c++ window. I have 2 arrays containing the x-points and y-points of the polygon. When printing the array the array shows correct except for the first element in both arrays.

On the Java side:

Polygon fillPoly = new Polygon(new int[] {200, 250, 300}, new int[] {400, 350, 400}, 3);
// 200, 400 | 250, 350 | 300, 400

g.fillPolygon(fillPoly);

//...

public void fillPolygon(final Polygon polygon) {
    fillPoly(polygon.xpoints, polygon.ypoints, polygon.npoints);
}

private native void fillPoly(final int[] xpoints, final int ypoints[], final int numPoints);

But the output on the data string are things like:

start: 693635144, 693771992 | Path: 693635144, 693771992 - 0, 0 - 718079568, 693635144 - | numPoints: 3
start: 35, 29 | Path: 35, 29 - 250, 350 - 300, 400 - | numPoints: 3
start: 35, 32 | Path: 35, 32 - 250, 350 - 300, 400 - | numPoints: 3
start: 35, -1437401059 | Path: 35, -1437401059 - 250, 4 - 300, 2949120 - | numPoints: 3
start: 35, 39573896 | Path: 35, 39573896 - 250, 1 - 300, 0 - | numPoints: 3
start: 47, 44 | Path: 47, 44 - 250, 350 - 300, 400 - | numPoints: 3
start: 53, 47 | Path: 53, 47 - 250, 350 - 300, 400 - | numPoints: 3
start: 53, 39589128 | Path: 53, 39589128 - 250, 1 - 300, 0 - | numPoints: 3
start: 56, 53 | Path: 56, 53 - 250, 350 - 300, 400 - | numPoints: 3
start: 56, 50 | Path: 56, 50 - 250, 350 - 300, 400 - | numPoints: 3
start: 39591176, 39591176 | Path: 39591176, 39591176 - 1, 12 - 99607256, 0 - | numPoints: 3
start: 71, 59 | Path: 71, 59 - 250, 350 - 300, 400 - | numPoints: 3
start: 71, 68 | Path: 71, 68 - 250, 350 - 300, 400 - | numPoints: 3

If I provide the points myself it works, but not with the jintArrays. How would I correctly retrieve the int values of the jint* and create D2D1::Point2F from them?


Solution

  • Your code stores the pointers to jxpoints, jypoints for later use, and releases the Java arrays. No wonder that sometimes these pointers point to data that has randomly changed. You probably need to copy the coordinates to some persistent C++ array, e.g. via shared_pointer<vector<jint>>:

    vector<jint> jxpoints(numPoints);
    env->GetIntArrayRegion(xpoint, 0, numPoints, &jxpoints[0]);