这节我们开始讲,c/c++中 unsigned 类型数据,跟java中数据类型的转换.和c/c++中回调函数的解决
1.unsigned 类型数据,跟java中数据的转换.
这里首先说下java和c基本数据类型所占空间大小.
java jni c/c++ 空间
boolean jboolean bool 8
byte jbyte char unsigned char 8
char jchar short unsigned short 16
short jshort shortunsigned short16
int jint int unsigned int 32
long jlong 32
float jfloat 32
double jdouble 64
上图可以看出,在c中的char只有一个字节,而java中的char有两个字节.那么出现几个问题.
<1.我怎么讲c中的char转换成java中的char?
(1.这个当然可以这个当然是可以直接复制. 从一个字节转换成两个字节,不会出现什么丢失的.
jchar ch = (jchar)c; //大概意思就这样.
(2.为什么要转换成java的char类型呢?为什么不直接转换成byte类型呢?它们都是一个字节的.
jbyte bt =(jbyte)c;
<2.如果是unsigned char呢?
(1.无符号的char也是一个字节,你可以转换成byte字节.
<3.char数组和unsigned char数组呢?
(1. char*可以通过env提供的方法,直接转换成string
char * ch;
jstring str = env->NewStringUTF(ch);
(2. unsigned char*转换成String可能会出现乱码的情况,那么我们可以转换成byte数组啊.
unsigned char* ch;
jbyte* bt = (jbyte*)ch; //转成byte数组
jbyteArray arr = env->NewByteArray(strlen(ch));
env->SetByteArrayRegion(arr,0,strlen(ch),bt); //将bt赋值给jbytearray了.
这下都给你bytearray 的java数组对象了,还不是为所欲为?
(3.jbyteArray转换成unsiged char*?
jbyteArray arr;
unsigned char* ch = (unsigned char*)env->GetByteArrayElements(arr,0); //就是这么简单
<4. char[] 和 char* 转换
2.c中回调函数的解决
<1.先给个c接口
//回调接口
typedef void (_stdcall *NET_FIND_DEVICE_CALLBACK)(T_RcvMsg *ptFindDevice, void *pUserData);
//回调函数
NET_API E_ReturnCode _stdcall Net_FindDevice(NET_FIND_DEVICE_CALLBACK func, void *pUserData);
<2.怎么解决这回调函数呢?我是这么解决的.
(1.先写netfindDevice的本地方法
JNIEXPORT jint JNICALL Java_com_viking_myapplication_JniMethod_NetFindDevice (JNIEnv *env, jobject jobj, jstring pUserData){ LOGE("Java_com_viking_myapplication_JniMethod_NetFindDevice"); jfindclass = env->GetObjectClass(jobj); jfindobject = jobj; char* puserdata = (char*)env->GetStringUTFChars(pUserData,0); jint result = Net_FindDevice(NET_FIND_DEVICE_CALLBACK1,(void*)puserdata); return result; }
(2.实现回调方法
void NET_FIND_DEVICE_CALLBACK1(T_RcvMsg *ptFindDevice, void *pUserData){//java回调方法 jmethodID jmethodid = env1->GetMethodID(jfindclass,"NetFindDeviceCallBack","(Lcom/viking/bean/TRcvMsg;Ljava/lang/String;)V"); jclass jtrcvmsgclass = env1->FindClass("com/viking/bean/TRcvMsg"); jmethodID jtrcvmsgid= env1->GetMethodID(jtrcvmsgclass,"<init>","()V");//创建回调方法的参数的java对象 jobject jtrcvmsgobj = env1->NewObject(jtrcvmsgclass,jtrcvmsgid); jclass jtnetsetupclass = env1->FindClass("com/viking/bean/TNetSetup"); jclass jtmacsetupclass = env1->FindClass("com/viking/bean/TMACSetup"); jmethodID jtnetsetupid = env1->GetMethodID(jtnetsetupclass,"<init>","()V"); jmethodID jtmacsetupid = env1->GetMethodID(jtmacsetupclass,"<init>","()V"); jobject jtnetsetupobj =env1 ->NewObject(jtnetsetupclass,jtnetsetupid); //对象一 jobject jtmacsetupobj =env1 ->NewObject(jtmacsetupclass,jtmacsetupid); //对象二*******************给回调方法的参数赋值*************************jstring puserdata = env1->NewStringUTF((char*)pUserData);//调用java中回调方法,参数(jtrcvmsgobj,puserdata); env1->CallVoidMethod(jfindobject,jmethodid,jtrcvmsgobj,puserdata); }(3.java中被调用的回调方法
/** * @param tRcvMsg * @param pUserData * 查找设备 */ public void NetFindDeviceCallBack(TRcvMsg tRcvMsg,String pUserData){ Log.e("TAG","NetFindDeviceCallBack"); if (mFindDeviceCallBack!=null){ mFindDeviceCallBack.CallBack(tRcvMsg,pUserData); } }
好像没什么好讲的.下节就讲讲jni开发中遇到哦bug吧.