Создать, заполнить и вернуть 2D String массив из собственного кода (JNI / NDK) - PullRequest
3 голосов
/ 20 мая 2011

Я нахожу этот фрагмент кода довольно сложным (не в последнюю очередь из-за того, что я начал играть с C только неделю назад).

Я изо всех сил пытался найти правильный синтаксис для правильного создания массива строк Java в C (то есть, массива объектов jstring, то есть объекта, который представляет массив объектов jstring). Я использовал следующие ресурсы, и из них я создал код, который компилируется. Я не уверен, что ошибка, возникающая впоследствии, связана с неправильным синтаксисом или по совершенно другой причине. Поскольку код в основном изолирован, я предполагаю, что синтаксис неправильный.

( Документация по собственному программированию Suns & Документация по Suns JNI )

Код компилируется, но после прохождения строки кода «FindClass» посылается сигнал SIGSEGV, который убивает процесс C:

jint size = 5;
jclass StringObject = (*env)->FindClass(env, "java/lang/String");
jobjectArray sampleMessage = (*env)->NewObjectArray(env, size, StringObject, NULL);
jobjectArray returnArray = (jobjectArray) (*env)->NewObjectArray(env, messageCount, &sampleMessage, 0);

Может ли кто-нибудь указать мне полезный ресурс для этого? Или подтвердите, что синтаксис правильный.

EDIT

Большая часть моей проблемы заключалась в том, что отладка этого кода вызывала проблему. У меня нет времени, чтобы сузить фактор воспроизведения, но перешагнуть через код JNI в gdb-клиенте через eclipse НЕ РАБОТАЕТ.

1 Ответ

16 голосов
/ 21 мая 2011

Чтобы получить jclass для типа строки, вы можете вызвать GetObjectClass() в одной из строк.Это работает:

Main.java

public class Main {

    static {
        System.loadLibrary("mynative");
    }

    private static native String[][] getStringArrays();

    public static void main(String[] args) {
        for (String[]  array : getStringArrays())
            for (String s : array)
                System.out.println(s);
    }
}

mynative.c

static jobjectArray make_row(JNIEnv *env, jsize count, const char* elements[])
{
    jclass stringClass = (*env)->FindClass(env, "java/lang/String");
    jobjectArray row = (*env)->NewObjectArray(env, count, stringClass, 0);
    jsize i;

    for (i = 0; i < count; ++i) {
        (*env)->SetObjectArrayElement(env, row, i, (*env)->NewStringUTF(env, elements[i]));
    }
    return row;
}

JNIEXPORT jobjectArray JNICALL Java_Main_getStringArrays(JNIEnv *env, jclass klass)
{
    const jsize NumColumns = 4;
    const jsize NumRows = 2;

    const char* beatles[] = { "John", "Paul", "George", "Ringo" };
    jobjectArray jbeatles = make_row(env, NumColumns, beatles);

    const char* turtles[] = { "Leonardo", "Raphael", "Michaelangelo", "Donatello" };
    jobjectArray jturtles = make_row(env, NumColumns, turtles);

    jobjectArray rows = (*env)->NewObjectArray(env, NumRows, (*env)->GetObjectClass(env, jbeatles), 0);

    (*env)->SetObjectArrayElement(env, rows, 0, jbeatles);
    (*env)->SetObjectArrayElement(env, rows, 1, jturtles);
    return rows;
}

Сборка, обработка ошибок опущенадля ясности.

...