您的位置:首页 > 编程语言 > Java开发

02-JNI-java相互调用

2016-10-11 21:01 246 查看

1.java传递数据给C

第一步:

在java中声明函数:

public native int add(int x,int y);

运行Android Tools工具,生成含有.cpp文件的/jni/  目录


第二步:

利用dos命令生成C的函数名



添加到src/jni/javatoc.c  文件中

在函数中实现 数据操作
// 用c进行加法运算,返回给java


JNIEXPORT jint JNICALL Java_com_uu_javatoc_JNI_add
(JNIEnv * env, jobject clazz, jint x, jint y){
return x+y;
}


第三步:

在相应的位置调用JNI函数


public void stringclick(View v){
String hello = jni.sayHelloInc("123456");
Toast.makeText(getApplicationContext(), hello, 0).show();
}


2.在C代码中使用logcat

Android.mk文件增加以下内容

LOCAL_LDLIBS += -llog


C代码中增加以下内容

#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函数中使用:

LOGD("length = %d",length);


3.JNI操作中常用到的 C转换函数(方法)

得到数组的长度

JArray 为jNI中c的自定义数据
jsize length = (*env)->GetArrayLength(env,jArray);


得到数组指针

int* arrayPointer = (*env)->GetIntArrayElements(env,jArray,NULL);


得到java 的字节码文件

jclass claz = (*env)->FindClass(env, "com/uu/ctojava/JNI");


得到java 类中的函数ID

jmethodID methodID = (*env)->GetMethodID(env, claz, "helloFromJava", "()V");


调用java 类中的函数

//无返回值
(*env)->CallVoidMethod(env, clazz, methodID,...);
有返回值
(*env)->CallIntMethod(env, clazz, methodID, x, y);
LOGD("sum = %d", sum)


将char* 转换成 jstring

jstring result =(*env)->NewStringUTF(env,"hello from java");


注意:第二个参数不能含有中文,虽为UTF-8 ,但确实不能,否则报错


3.jstring转换成char* 分析

函数如下所示:

个人分析,转载请注明出处

char* _JString2CStr(JNIEnv* env, jstring jstr) {

char* rtn = NULL;
//得到String 的字节码文件
jclass clsstring = (*env)->FindClass(env, "java/lang/String");

//将“GB2312” 转换成    jstring类型的数据
jstring strencode = (*env)->NewStringUTF(env,"GB2312");

//获得java 中 String的getBytes 方法
jmethodID mid = (*env)->GetMethodID(env, clsstring, "getBytes", "(Ljava/lang/String;)[B");

//将jstring 类型的jstr    转换成  jbyteArray 类型的数组
jbyteArray barr = (jbyteArray)    (*env)->CallObjectMethod(env, jstr, mid, strencode); // String .getByte("GB2312");

//得到  字符数组(barr) 的 长度
jsize alen = (*env)->GetArrayLength(env, barr);

//得到  字符数组(barr) 的 指针
jbyte* ba = (*env)->GetByteArrayElements(env, barr, JNI_FALSE);

if(alen > 0) {
//为char *  类型的 rtn 开辟内存空间
rtn = (char*)malloc(alen+1); //"\0"
//将 字符数组   copy  到rtn   中
memcpy(rtn, ba, alen);
// 加  0 返回
rtn[alen]=0;
}
(*env)->ReleaseByteArrayElements(env, barr, ba,0);
return rtn;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  交叉编译 JNI andoird