在JNI中追加字节数组

时间:2017-07-17 10:35:26

标签: java android c++ java-native-interface append

追加功能从 Java 转换为 JNI 时,我遇到了麻烦。如果有人可以帮助我,我会很感激。

爪哇

在java中附加函数

/*
private byte[] append(byte[]... dtIn) {

    // get dtIn length
    int length = 0;
    for (byte[] d : dtIn) {
        length += d.length;
    }

    // allocate memory
    ByteBuffer b = ByteBuffer.allocate(length);

    // append dtIn
    for (int i = 0; i < dtIn.length; i++) {
        b.put(dtIn[i]);
    }
    return b.array();
}
*/


private native byte[] append(byte[]... dtIn);

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

JNI

全球常数

const char *CLS_BYTE_BUFFER = "java/nio/ByteBuffer";
const char *MID_ALLOCATE = "allocate";
const char *SIG_ALLOCATE = "(I)Ljava/nio/ByteBuffer;";
const char *MID_PUT= "put";
const char *SIG_PUT = "(B)Ljava/nio/ByteBuffer;";
const char *MID_ARRAY = "array";
const char *SIG_ARRAY = "()[B";

全局变量

JavaVM *_jvm;
jclass _clsByteBuffer;
jmethodID _midAllocate, _midPut, _midArray;

执行System.loadLibrary(“mylibs”)时将调用此函数。

JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM *jvm, void *reserved) {
    jclass clsByteBuffer;

    JNIEnv *env;

    _jvm = jvm;
    if (jvm->GetEnv((void **) &env, JNI_VERSION_1_6)) {
        return JNI_ERR;
    }

    // ByteBuffer
    clsByteBuffer = env->FindClass(CLS_BYTE_BUFFER);
    if (clsByteBuffer == NULL || tryCatch()) {
        return JNI_ERR;
    }

    _clsByteBuffer = (jclass) env->NewWeakGlobalRef(clsByteBuffer);
    if (_clsByteBuffer == NULL || tryCatch()) {
        return JNI_ERR;
    }

    // allocate
    _midAllocate = env->GetStaticMethodID(_clsByteBuffer, MID_ALLOCATE, SIG_ALLOCATE);
    if (_midAllocate == NULL || tryCatch()) {
        return JNI_ERR;
    }

    // put
    _midPut = env->GetMethodID(_clsByteBuffer, MID_PUT, SIG_PUT);
    if (_midPut == NULL || tryCatch()) {
        return JNI_ERR;
    }

    // array
    _midArray = env->GetMethodID(_clsByteBuffer, MID_ARRAY, SIG_ARRAY);
    if (_midArray == NULL || tryCatch()) {
        return JNI_ERR;
    }

    return JNI_VERSION_1_6;
}

附加功能(问题在这里!!)

JNIEXPORT jbyteArray JNICALL
Java_com_company_myapp_activity_test_append(JNIEnv *env, jobject instance, jobjectArray dtIn) {

    // This works 
    JNIEnv *e = getEnv();
    if (e == NULL || instance == NULL || dtIn == NULL) {
        return NULL;
    }

    // This works 
    jint length = 0;
    for (jint i = 0; i < e->GetArrayLength(dtIn); i++) {
        jbyteArray item = (jbyteArray) e->GetObjectArrayElement(dtIn, i);
        length = length + e->GetArrayLength(item);
    }

    // Allocate buffers
    jobject buffer = e->CallStaticObjectMethod(_clsByteBuffer, _midAllocate, length);
    if (buffer == NULL || tryCatch()) {
        return NULL;
    }

   // This does not worked ??? 
    for (jint i = 0; i < e->GetArrayLength(dtIn); i++) {
        jbyteArray item = (jbyteArray) e->GetObjectArrayElement(dtIn, i);

        e->CallVoidMethod(buffer, _midPut, item);
    }
    return (jbyteArray) e->CallObjectMethod(buffer, _midArray);
}

1 个答案:

答案 0 :(得分:0)

我的问题已经解决,错误发生在 put 签名的持续输入错误,少了 [标记。

替换

const char *SIG_PUT = "(B)Ljava/nio/ByteBuffer;";

const char *SIG_PUT = "([B)Ljava/nio/ByteBuffer;";