开发者

map return type of C++ function to byte[][] in Java

开发者 https://www.devze.com 2023-02-04 02:13 出处:网络
I have a c++ function declared as unsigned char** classify I am using the following interface file in SWIG

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.


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.


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;
}


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?"

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号