tags:

views:

916

answers:

4

What data types are usually used in C API implementation for storing byte streams? How can I convert this type to jbyteArray?

+1  A: 

That'd be (const) unsigned char * representing a block of memory holding the bytes themselves, coupled with a size_t telling you the number of bytes.

This thread seems to go over how to create a suitable Java type (NewByteArray() is the function).

unwind
A: 

You question is not very clear.

Assuming you have some bytes in C representing characters, the best idea is to get the bytes into Java and convert them to text there using Java's byte conversions.

In JNI you simply need to materialize a Java array, either by using JNI to instantiate one, or by passing a reference in as a parameter (for which you still need to "materialize" a pointer in the JNI code).

I have done this latter thing before, so here is the code FYI. This JNI call used an AS/400 C API to read a database record and return the bytes back to Java - the Java code then used record format information to extract the fields into Strings. Hope this is of some help:

JNIEXPORT jboolean JNICALL Java_com_xxx_DB2File_jniRead(JNIEnv *jep, jobject thsObj,                    
 jlong handle, jint readOp, jbyteArray jvaDta, jint jvaDtaMax, jint flags) {                                                
    OBJDTA           *odp;                                                                                                  
    jbyte            *jniDta;                                                                                               
    _RIOFB_T         *fbp;                                                                                                  

    thsObj=thsObj;                                                                                                          
    if((odp=getDataspace(handle))==NULL) {                                                                                  
        throwEscape(jep,90003,"Invalid handle for dataspace in jniRead()");                                                 
        return JNI_FALSE;                                                                                                   
        }                                                                                                                   
    jniDta=(*jep)->GetByteArrayElements(jep,jvaDta,0);                                                                      

    // read database record here

    if(fbp->num_bytes<=0) {                                                                                                 
        (*jep)->ReleaseByteArrayElements(jep,jvaDta,jniDta,JNI_ABORT); /* do not copy changed array back to java */         
        return JNI_FALSE;                                                                                                   
        }                                                                                                                   
    if(fbp->num_bytes!=odp->rcdLen) {                                                                                       
        byte             errtxt[201];                                                                                       

        asd_errtxt(errno,errtxt,sizeof(errtxt));                                                                            
        (*jep)->ReleaseByteArrayElements(jep,jvaDta,jniDta,JNI_ABORT); /* do not copy changed array back to java */         
        throwEscape(jep,90204,"Native function jniRead failed.  Got %i, expected %i (%s)",fbp->num_bytes,odp->rcdLen,       
         errtxt);                                                                                                           
        return JNI_FALSE;                                                                                                   
        }                                                                                                                   
    (*jep)->ReleaseByteArrayElements(jep,jvaDta,jniDta,0); /* copy changed array back to java */                            
    return JNI_TRUE;                                                                                                        
    }
Software Monkey
A: 

You don't need to convert them. The types jbyteArray and char* are compatible.

Java declaration:

private static native int doSomething(bate[] string, int length);

C delaration:

JNIEXPORT jint JNICALL Java_package_class_doSomething(JNIEnv *env, jclass jc, jbyteArray string, jint length) {
    int i;
    for (i = 0; i < length; i++) {
        // read string[i]
    }
}

You can pass values back to java the same way. But make sure the length of the byte array is initialized BEFORE calling the C function.

Eduard Wirch
+1  A: 

See the Java_ReadFile_loadFile example where they use NewByteArray() and return it directly.

http://java.sun.com/developer/onlineTraining/Programming/JDCBook/jnistring.html

Rolf Kristensen