您的位置:首页 > 移动开发 > Android开发

Android studio NDK开发 从入门到实践四

2017-12-27 11:06 441 查看
这节我们开始讲,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吧.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息