Reputation: 11915
I have a c++ function declared as
unsigned char** classify
I am using the following interface file in SWIG
%module PWrap
%include "std_string.i"
%include "arrays_java.i"
%apply byte[][] {unsigned char**};
%{
#include "Classifier.h"
%}
%include "Classifier.h"
which generated some files, including a SWIGTYPE_p_p_unsigned_char object
Now, here's where I try to use this C++ function in Java:
SWIGTYPE_p_p_unsigned_char data = pc.classify();//this works, but I can't do anything with the data object execept pass it to other C++ functions expecting unsigned char**
byte[][] data2 =pc.classify();//this does not work - throws compile time error
So what am I doing wrong to get this mapping working correctly? I know the dimensions of the matrix, because I pass in the args to the C++ function to set everything up. In other words, I'd be happy with getting the data back in any way as long as I could cast it to byte somehow back in Java.
Upvotes: 2
Views: 923
Reputation: 1109
Have a look at http://www.ibiblio.org/pub/languages/fortran/append-c.html "Why a double pointer can't be used as a 2D array?"
Upvotes: 1
Reputation: 1542
I'd better use use direct JNI instead of SWIG to have full control over such data types.
Anyway returning char **
is not effective because array pinning can't be used. Probably that's why your SWIG wrapper does not do what you want - your classify
should accept char **
as a parameter and not return it. I don't know SWIG so here is some JNI code.
Java source:
package my;
public class Classifier {
public native void init(); // initialize _ptr with a new Classifier
public native void cleanup(); // destroy Classifier
public native byte[][] classify();
private long _ptr;
}
Method definition in C/C++:
Classifier *getClassifierInstance(JNIEnv *env, jobject obj) {
jfieldID id = env->GetFieldID(env->GetObjectClass(obj), "_ptr", "J");
return (id == NULL) ? NULL : ((Classifier *)env->GetLongField(obj, id));
}
JNIEXPORT jobjectArray JNICALL
Java_my_Classifier_classify(JNIEnv *env, jobject obj) {
Classifier *classifier = getClassifierInstance(env, obj);
char **ptr = classifier->classify();
jobjectArray result = NewObjectArray(env, MATRIX_HEIGHT, FindClass(env, "[B"), NewByteArray(env, 0));
for (int i = 0; i < MATRIX_HEIGHT; ++i) {
jbyteArray row = NewByteArray(env, MATRIX_WIDTH);
SetByteArrayRegion(env, row, 0, MATRIX_WIDTH, ptr[i]);
SetObjectArrayElement(env, result, i, row);
}
return result;
}
Upvotes: 2
Reputation: 146940
A char** is not a byte[][]. Only single-dimensional arrays can decay into pointers. What you have got back is an array of pointers to arrays, not an array of arrays.
Upvotes: 3