Jni 常用工具函数

Jni编程会用到的工具函数,做积累

1. 打开文件路径,返回文件描述符给Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//打开路径文件,并抬FileDescriptor
jobject  openFile(JNIEnv *env, jstring path, jint flags){
     int  fd;
     jobject mFileDescriptor;
 
     /* Opening device */
     {
         jboolean iscopy;
         const  char  *path_utf = env->GetStringUTFChars(path, &iscopy);
         fd = open(path_utf, O_RDWR | flags);
         env->ReleaseStringUTFChars(path, path_utf);
         if  (fd == -1)
         {
             /* Throw an exception */
             LOGE( "Cannot open port" );
             return  NULL;
         }
     }
 
     /* Create a corresponding file descriptor */
     {
         jclass cFileDescriptor = env->FindClass( "java/io/FileDescriptor" );
         jmethodID iFileDescriptor = env->GetMethodID(cFileDescriptor,  "<init>" "()V" );
         jfieldID descriptorID = env->GetFieldID(cFileDescriptor,  "descriptor" "I" );
         mFileDescriptor = env->NewObject(cFileDescriptor, iFileDescriptor);
         env->SetIntField(mFileDescriptor, descriptorID, (jint)fd);
     }
 
     return  mFileDescriptor;
}


2. Char转换成String

1
2
3
4
5
6
7
8
9
10
11
//char * to string
jstring charToString(JNIEnv *env,  const  char  *chr){
     LOGI( "charToString: %s\n" , chr);
     jclass strClass = env->FindClass( "java/lang/String" );
     jmethodID strConstruct = env->GetMethodID(strClass,  "<init>" "([BLjava/lang/String;)V" );
     jbyteArray bytes = env->NewByteArray( strlen (chr));
     env->SetByteArrayRegion(bytes, 0,  strlen (chr), (jbyte*)chr);
     jstring encoding = env->NewStringUTF( "utf-8" );
 
     return  (jstring)env->NewObject(strClass, strConstruct, bytes, encoding);
}


3. String转换为Char

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//jstring to char*
char * jstringToChar(JNIEnv* env, jstring jstr)
{
     char * rtn = NULL;
     jclass clsstring = env->FindClass( "java/lang/String" );
     jstring strencode = env->NewStringUTF( "utf-8" );
     jmethodID mid = env->GetMethodID(clsstring,  "getBytes" "(Ljava/lang/String;)[B" );
     jbyteArray barr= (jbyteArray)env->CallObjectMethod(jstr, mid, strencode);
     jsize alen = env->GetArrayLength(barr);
     jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE);
 
     if  (alen > 0)
     {
         rtn = ( char *) malloc (alen + 1);
         memcpy (rtn, ba, alen);
         rtn[alen] = 0;
     }
 
     env->ReleaseByteArrayElements(barr, ba, 0);
     return  rtn;
}


4. 上层传一个ByteBuffer给Jni用

Java:

   
   
private ByteBuffer mImageBuffer;
mImageBuffer = ByteBuffer.allocateDirect(mImageBufferSize);
ret = setDirectBuffer(mImageBuffer, mImageBufferSize);
Jni:
    
    
jint Java_com_camera_simplewebcam_CameraPreview_setDirectBuffer(JNIEnv *env, jobject thiz,
jobject jbuf, jint jlen) {
 
char *pImageBuf = NULL;
//获取Buffer首地址
pImageBuf = (char *)(*env)->GetDirectBufferAddress(env, jbuf);
if (NULL == pImageBuf) {
LOGE("Failed to get direct buffer");
return -1;
}
return 0;
}

5. 色彩Buffer转换成Bitmap类。
在UVC中把一帧的buffer转换成上层需要显示的Bitmap。Android.mk里要加入库LOCAL_LDLIBS    := -ljnigraphics

   
   
void
Java_com_camera_simplewebcam_CameraPreview_pixeltobmp( JNIEnv* env,jobject thiz,jobject bitmap){
 
jboolean bo;
AndroidBitmapInfo info;
void* pixels;
int ret;
int i;
int *colors;
 
int width=0;
int height=0;
//提取bmp信息
if ((ret = AndroidBitmap_getInfo(env, bitmap, &info)) < 0) {
LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret);
return;
}
width = info.width;
height = info.height;
 
if(!rgb || !ybuf) return;
 
if (info.format != ANDROID_BITMAP_FORMAT_RGBA_8888) {
LOGE("Bitmap format is not RGBA_8888 !");
return;
}
//bitmap提取buf
if ((ret = AndroidBitmap_lockPixels(env, bitmap, &pixels)) < 0) {
LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
}
 
colors = (int*)pixels;
int *lrgb =NULL;
lrgb = &rgb[0];
//把目录buf拷贝到bitmap的buffer里
for(i=0 ; i<width*height ; i++){
*colors++ = *lrgb++;
}
 
AndroidBitmap_unlockPixels(env, bitmap);
}

猜你喜欢

转载自blog.csdn.net/shell812/article/details/49763155
今日推荐