- java传递各类型参数给C的要点在于要将传递过来的数据类型转换成C认识的数据类型,C返回时又要转换成java认识的数据类型。下图是java和C数据类型的对比表。
传递int类型数据
- 对比前面两个表,得知java中int就是c中的jint,并且两种数据类型都是占4个字节,因此可不用转换,直接计算并返回。
Java代码:
public native int add(int x, int y);
C中实现代码:
JNIEXPORT jint JNICALL Java_com_zhong_jnipassdata_JNI_add
(JNIEnv * env, jobject clazz, jint x, jint y){
return x+y;
}
传递String类型数据
- 由于String类型c并不认识,所以要将string类型转换成char类型,这里需要用到一个将string转换成char的算法。然后再将char类型转换成string类型返回给java。
- 将string转换成char的算法。
**
* 把一个jstring转换成一个c语言的char* 类型.
*/
char* _JString2CStr(JNIEnv* env, jstring jstr) {
char* rtn = NULL;
jclass clsstring = (*env)->FindClass(env, "java/lang/String");
jstring strencode = (*env)->NewStringUTF(env,"GB2312");
jmethodID mid = (*env)->GetMethodID(env, clsstring, "getBytes", "(Ljava/lang/String;)[B");
jbyteArray barr = (jbyteArray)(*env)->CallObjectMethod(env, jstr, mid, strencode); // String .getByte("GB2312");
jsize alen = (*env)->GetArrayLength(env, barr);
jbyte* ba = (*env)->GetByteArrayElements(env, barr, JNI_FALSE);
if(alen > 0) {
rtn = (char*)malloc(alen+1); //"\0"
memcpy(rtn, ba, alen);
rtn[alen]=0;
}
(*env)->ReleaseByteArrayElements(env, barr, ba,0);
return rtn;
}
- java代码
public native String sayHelloInC(String str);
- c代码
JNIEXPORT jstring JNICALL Java_com_zhong_jnipassdata_JNI_sayHelloInC
(JNIEnv * env, jobject clazz, jstring jstr){
//将jstring类型转换成c中的char类型
char* str = _JString2CStr(env,jstr);
//得到字符串的长度
int length = strlen(str);
int i ;
//改变一下字符串的值
for (i = 0; i < length; i++) {
*(str+i) += 2;
}
//将c中char类型转换成java中的string类型返回
return (*env) -> NewStringUTF(env,str);
}
传递整型数组
- java代码
public native int[] passArray(int[] intArray);
- c代码
JNIEXPORT jintArray JNICALL Java_com_zhong_jnipassdata_JNI_passArray
(JNIEnv * env, jobject clazz, jintArray array){
//得到数组长度
jsize length = (*env)->GetArrayLength(env,array);
//输出log
LOGI("数组的长度:%d",length);
//得到数组首地址
jint* firstPointer = (*env)->GetIntArrayElements(env,array,NULL);
int i = 0;
for ( i= 0; i< length; i++) {
//让数组中每个值都加上10
*(firstPointer+i) += 10;
}
return array;
}
在c代码中使用logcat
Android.mk文件增加以下内容
LOCAL_LDLIBS += -llogC代码中增加以下内容
#include <android/log.h>
#define LOG_TAG "System.out"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
- C代码中使用logcat, 例:
LOGI("info\n,%d",length);
LOGD("debug\n");