java数据结构默认均为有符号数,而通过jni转换到c/c++层,却不一定是有符号数。
如若在java中存储的即为无符号数,则在jni中可将jbyte直接进行类型转换。
若进行操作,则可在计算时,先将byte&0xff,这样即可转换为32位数据,而后再进行计算。
转换方式如下:
1、jbyteArray转换为unsigned char*
Java
1 public class example { 2 public final static native void set_Foo_array(long jarg0, short[] jarg1); 3 public final static native short[] get_Foo_array(long jarg0); 4 }
c++ code:
class Foo { public: unsigned char array[10]; }; extern "C"{ JNIEXPORT void JNICALL Java_example_set_1Foo_1array(JNIEnv *jenv, jclass jcls, jlong jarg0, jshortArray jarg1) { Foo *arg0 ; unsigned char *arg1 ; int i ; jshort* jarg1_carray ; jsize jarg1_len = jenv->GetArrayLength(jarg1) ; arg0 = *(Foo **)&jarg0; jarg1_carray = jenv->GetShortArrayElements(jarg1, 0); arg1 = (unsigned char *) malloc(jarg1_len * sizeof(unsigned char )); for(i=0; i<jarg1_len; i++) arg1[i] = (unsigned char )jarg1_carray; { int i; for (i=0; i<10; i++) arg0->array[i] = arg1[i]; } jenv->ReleaseShortArrayElements(jarg1, jarg1_carray, 0); free(arg1); }} extern "C"{ JNIEXPORT jshortArray JNICALL Java_example_get_1Foo_1array(JNIEnv *jenv, jclass jcls, jlong jarg0) { jshortArray jresult = 0 ; Foo *arg0 ; unsigned char *result ; jshort* jnitype_ptr = 0 ; int k ; arg0 = *(Foo **)&jarg0; result = (unsigned char *)(unsigned char *) (arg0->array); jresult = jenv->NewShortArray(10); jnitype_ptr = jenv->GetShortArrayElements(jresult, 0); for (k=0; k<10; k++) jnitype_ptr[k] = (jshort)result[k]; jenv->ReleaseShortArrayElements(jresult, jnitype_ptr, 0); return jresult; }} The code comes from the output of swig (www.swig.org) - a tool which generated the JNI and Java code given the C++ class definition above.
2、char*转jbyte
1 static .. jvm; // ref to jvm 2 static jobject printAPI; // the static class ref 3 static jmethodID loadBuffer; // the static method ref 4 5 void loadImage(int x, int y, int width, int height, char* pixels, int maxWidth, int maxHeight){ 6 JNIEnv* env; 7 jint result = (*jvm)->GetEnv(jvm, &env, JNI_VERSION_1_2); 8 if(result < 0 || env == NULL){ 9 fprintf(stderr, "Error finding JNI environment\n"); 10 }else{ 11 int i, size = width*height*3; 12 jbyteArray rgb; // the byte array 13 jbyte* v; // array of jbytes for transfer operation 14 15 /* Transfer char* to jbyteArray */ 16 rgb = (*env)->NewByteArray(env, width * height *3); 17 v = malloc( (width * height *3) * sizeof(jbyte)); 18 if( !rgb || !v ){ 19 fprintf(stderr, "Error allocating memory in loadImage(..)"); 20 return; 21 } 22 for(i=0;i<size; ++i) v[i] = (jbyte) pixels; 23 24 (*env)->SetByteArrayRegion(env, rgb, 0, size, v); 25 26 27 28 /* send pixel dump to gui */ 29 30 (*env)->CallStaticIntMethod(env, printAPI, loadBuffer, x, y, width, height, rgb); 31 32 } 33 34 } 35 36 37 38 the method on the java side is 39 static void loadByteArray( int x, int y, int w, int h, byte[] rgb ){..} 40 Hope it helps.