The Java char and C char types are incompatible, it would probably be better to pass byte[] to C, and then convert each element on demand.
Something like that:
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); }
jbyteArray is nothing more than a stub type defined in jni.h :
struct _jobject; typedef struct _jobject *jobject; typedef jobject jarray; typedef jarray jbyteArray;
In fact, it does not contain any data. It is more or less just a memory address.
To get elements from it, we pass it GetByteArrayElements (since the type was byte[] ), which the VM can request to retrieve the elements in the C style array (It may or may not make a copy. See Doc)
The same is done for array length.
To tell VM, we ended up working with an array. We call ReleaseArrayElements .
In addition, jbyte is defined as signed char , so just using the result of GetByteArrayElements as unsigend char* instead of jbyte* is safe in this case.