j2me中的KNI简介

J2ME杂谈(2)
J2ME虚拟机的移植。
在嵌入式系统中的JAVA虚拟机由多个版本,用的最广的是SUN发布的KVM。K的意思是这个虚拟机的大小是以kilo byte来衡量的(size小)。我们这里主要介绍一下KVM的移植。需要声明的是我的这些介绍只是一些原理上的,所以不会一个是step by step的移植教程。在需要的时候,我会尽可能的拿实际的代码来示范。
因为JAVA与C的运行环境在对stack,静态变量, 类和指针的管理都存在一些差别,所以在从Java调用Native的C或C++ CODE时,增加了一层KNI(K native interfatce)接口用于解决转换这些问题。即KNI是KVM在成功调用Native 的C code Method时所需要依靠的一些辅助函数。KNI的所有实现都包含在Kni.h和Kni.cpp(可从sun的官网上下载cldc的最新版本)中,作为Interface必定是双向的,主要功能包括获得由KVM向Native C传递的参数, 处理Naïve C code的返回值等等。
KNI作为一个移植过程的重要工具,大家必须非常熟悉。关于KNI API的介绍,可在google或baidu上搜索。也可以发邮件给我。
这里举一个例子:
KNIEXPORT KNI_RETURNTYPE_BOOLEAN 
Java_com_sun_midp_io_j2me_cbs_CBSImpl_readMsg() { 
CB_APP_MSG_S *msg = NULL; 
if ((msg = getCBSMessage()) == NULL) { 
KNI_ReturnBoolean(KNI_FALSE); //返回值 
} 
KNI_StartHandles(3); //声明native方法中将使用3个句柄 
KNI_DeclareHandle(clazz); //声明句柄clazz 
KNI_DeclareHandle(obj); //声明句柄obj 
KNI_DeclareHandle(cb_content); //声明句柄cb_content 
KNI_GetParameterAsObject(1, obj); //获得参数1并赋给obj 
KNI_GetObjectClass(obj, clazz); //获得obj所属类的句柄存于clazz中 
KNI_SetIntField(obj, KNI_GetFieldID(clazz, \"channel\", \"I\"), (jint)msg->channelNumber); //获得成员变量channel的指针;将msg->channelNumber赋给channel
KNI_SetByteField(obj, KNI_GetFieldID(clazz, \"encoding\", \"B\"), ENCODING_UNICODE); //获得成员变量encoding的指针;将ENCODING_UNICODE赋给encoding 
KNI_SetIntField(obj, KNI_GetFieldID(clazz, \"msg_len\", \"I\"), getMsgLen(msg->cbContent)); 
KNI_GetObjectField(obj, KNI_GetFieldID(clazz, \"cb_content\", \"[B\"), cb_content); //获得成员数组的指针 
KNI_SetRawArrayRegion(cb_content, 0, CB_MAX_MSG_SIZE, (jbyte *)msg->cbContent); //清0 
midpFree(msg); 
msg = NULL; 
KNI_EndHandles(); //与starthandle配对使用,表示结束 
KNI_ReturnBoolean(KNI_TRUE); 
} 

你可能感兴趣的:(j2me)