从本机代码(JNI / NDK)创建,填充和返回2D String数组

时间:2011-05-20 10:36:19

标签: java string multidimensional-array java-native-interface

我发现这段特殊代码非常困难(尤其是因为我一周前才开始使用C语言)。

我一直在努力寻找正确的语法来正确地在C中创建一个java字符串数组(即一个jstring对象数组,即一个表示jstring对象数组的对象)。我一直在使用以下资源,从中我已经构建了编译的代码。我不确定之后发生的错误是由于语法错误还是由于完全独立的原因。由于代码大多是孤立的,我假设语法不正确。

Suns Native Programming Documentation& Suns JNI documentation

代码编译但在传递“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);

有人能指出我这个有用的资源吗?或者确认语法是否正确。

修改

我的大部分问题是调试此代码导致了问题。我没有时间缩小再现因素,但是通过eclipse在gdb-client中踩过JNI代码不起作用。

1 个答案:

答案 0 :(得分:16)

要获取行类型的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;
}

为清晰起见,忽略了构建,错误处理。