сопоставить возвращаемый тип функции C ++ с байтом [] [] в Java - PullRequest
2 голосов
/ 12 января 2011

У меня есть функция c ++, объявленная как

символ без знака ** классификация

Я использую следующий файл интерфейса в SWIG

%module PWrap
%include "std_string.i"
%include "arrays_java.i"

%apply byte[][] {unsigned char**};

%{
#include "Classifier.h"
%}

%include "Classifier.h"

, который сгенерировал некоторые файлы, включая объект SWIGTYPE_p_p_unsigned_char

Теперь я попытаюсь использовать эту функцию C ++ в 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

Так, что я делаю неправильно, чтобы это отображение работало правильно? Я знаю размеры матрицы, потому что я передаю аргументы в функцию C ++, чтобы все настроить. Другими словами, я был бы рад получить данные любым способом, если бы я мог как-то преобразовать их в байт обратно в Java.

Ответы [ 3 ]

3 голосов
/ 12 января 2011

Символ ** не является байтом [] [].Только одномерные массивы могут распадаться на указатели.То, что вы получили, это массив указателей на массивы, а не массив массивов.

2 голосов
/ 20 января 2011

Я бы лучше использовал прямой JNI вместо SWIG, чтобы иметь полный контроль над такими типами данных.

В любом случае возвращение char ** неэффективно, поскольку закрепление массива не может бытьиспользуемый.Вероятно, поэтому ваша оболочка SWIG не делает то, что вы хотите - ваш classify должен принять char ** в качестве параметра и не возвращать его.Я не знаю SWIG, поэтому вот код JNI.

Источник Java:

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

Определение метода в 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;
}
1 голос
/ 24 января 2011

Посмотрите на http://www.ibiblio.org/pub/languages/fortran/append-c.html "Почему двойной указатель нельзя использовать в качестве двумерного массива?"

...