2017-07-17 2 views
0

Ich habe Probleme bei der Konvertierung der Funktion von Java zu JNI anhängen. Wenn mir jemand helfen kann, würde ich das schätzen.Anfügen Byte-Arrays in JNI

Java

Anfügen Funktion in 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

Globale Konstante

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

Globale Variablen

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

Diese Funktion wird aufgerufen, wenn System.loadLibrary ("mylibs") ausgeführt wird.

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

Anfügen Funktion (PROBLEM IN HERE !!)

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); 
} 
+0

'javap java/NiO/ByteBuffer es | grep -A 2 "put (byte" ', um die verschiedenen Signaturen von put mit Byte zu erhalten. Wenn Sie SIG_PUT für eine bestimmte Methode benennen, würden Sie nichts falsch machen. –

+0

Danke, dass Sie darauf hingewiesen haben – Ihdina

Antwort

0

Mein Problem gelöst wird, tritt der Fehler aufgrund eines konstanten Schreibfehlers für Unterschrift setzen, weniger [ Marke.

ersetzen

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

mit

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