How can I pass a byte array to a C function that takes a char* as a parameter using the Java Native Interface?


User 6373390:

So I need to call a C function from Java using JNI. I've been able to do this successfully when passing in different data types (creating native variables, header files, shared libraries, etc.), but can't get it to work with byte arrays. Here is my C function:

#include <stdio.h>
void encrypt(int size, unsigned char *buffer);
void decrypt(int size, unsigned char *buffer);

void encrypt(int size, unsigned char *buffer){
    for(int i=0; i<size; i++){
        unsigned char c = buffer[i];
        printf("%c",c);
    }
}
void decrypt(int size, unsigned char *buffer){
    for(int i=0; i<size; i++){
        unsigned char c = buffer[i];
        printf("%c",c);
    }
}

Here is my java code (I understand that after using this as a header file, I have to replace the C function declaration with the JNI code in the header file)

class Tester{
    public native void encrypt(int size, char *buffer);
    public native void decrypt(int size, char *buffer);
    static{
    System.loadLibrary("buffer");
    {
    public static void main(String[] args){
        Tester test = new Tester();
        String hello = "hello";
        byte[] byteHello = hello.getBytes();
        test.encrypt(5,byteHello);
        test.decrypt(5,byteHello);
    }
}

I know Java doesn't support char* types, that's why I'm getting errors when trying to compile. Maybe I should change the type to char[] in Java? Anyway, my goal is to be able to pass a byte array from Java into my C function, iterate over that byte array and print out each element.

Jon Furney:

Java charand C charare type incompatible, it's better to pass byte[]C to C and then convert each element on demand.


Follow these principles:

Main.java:

//...Code to load library...

public static void main(String[] args) {
    passBytes("hello".getBytes());
}

public static native void passBytes(byte[] bytes);

Main.c:

#include "Main.h" // Main.h is generated

JNIEXPORT void JNICALL Java_Main_passBytes
  (JNIEnv *env, jclass clazz, jbyteArray array) {
    unsigned char* buffer = (*env)->GetByteArrayElements(env, array, NULL);
    jsize size = (*env)->GetArrayLength(env, array);

    for(int i = 0; i < size; i++) {
        printf("%c", buffer[i]);
    }

    (*env)->ReleaseByteArrayElements(env, array, buffer, JNI_ABORT);
 }

jbyteArrayJust a stub type, defined in jni.h:

struct _jobject;
typedef struct _jobject *jobject;
typedef jobject jarray;
typedef jarray jbyteArray;

It doesn't actually contain any data. It's more or less just a memory address.

In order to get an element from it, we pass it to (of type ) and can then ask the VM to retrieve the element in the C-style array. (It may or may not copy. See doc)GetByteArrayElementsbyte[]

The same goes for the array length.

Tell the VM that we are done with the array operation. We call .ReleaseArrayElements

Also, jbytesince will be defined as signed char, it is safe to just use the result GetByteArrayElementsas a unsigend char*substitute in this case .jbyte*

Related


Pass pointer to char array as parameter to function - C

Macaque In the function declaration below, the first parameter is a String, specifically an array of chars, and the third parameter is a pointer to an integer. Is the second parameter a pointer to an array of characters? In other words, a pointer to a pointer?

Pass pointer to char array as parameter to function - C

Macaque In the function declaration below, the first parameter is a String, specifically an array of chars, and the third parameter is a pointer to an integer. Is the second parameter a pointer to an array of characters? In other words, a pointer to a pointer?

Pass pointer to char array as parameter to function - C

Macaque In the function declaration below, the first parameter is a String, specifically an array of chars, and the third parameter is a pointer to an integer. Is the second parameter a pointer to an array of characters? In other words, a pointer to a pointer?

Pass pointer to char array as parameter to function - C

Macaque In the function declaration below, the first parameter is a String, specifically an array of chars, and the third parameter is a pointer to an integer. Is the second parameter a pointer to an array of characters? In other words, a pointer to a pointer?

Pass a char array to a function that takes a char pointer

Bruno Ely In C, why can I pass a character array to a function that takes a char *as a parameter, but not the address of the array to a function that takes a char **? UPDATE: Interestingly, changing the parameter type char* qux[12]to does n't completely change