【问题标题】:Append byte arrays in JNI在 JNI 中追加字节数组
【发布时间】:2017-12-21 20:33:19
【问题描述】:

append 函数从 Java 转换为 JNI 时遇到问题。如果有人能在这方面提供帮助,我将不胜感激。

Java

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

【问题讨论】:

  • javap -s java/nio/ByteBuffer | grep -A 2 "put(byte" 获取put with byte的各种签名。如果您将 SIG_PUT 命名为特定方法,则不会出错。

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


【解决方案1】:

我的问题解决了,这个错误是由于 put 签名的持续输入错误,少了 [ 标记。

替换

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

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

【讨论】:

    猜你喜欢
    • 2013-03-21
    • 1970-01-01
    • 2011-10-07
    • 2013-01-06
    • 1970-01-01
    • 1970-01-01
    • 2014-11-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多