JNI开发学习之调用C方法

作者: maoqitian | 来源:发表于2016-12-28 11:57 被阅读811次

最近接触到Android编程下的JNI开发,根据上一篇文章环境配置,下面我想通过我的学习记录一下实践笔记。

首先按照上一篇文章建好工程,可以不使用系统提供创建好的native-lib文件,而是自己创建一个 javacall.c
上一篇文章地址:
Android studio2.2 构建C/C++工程

project.png

其次,编辑新建JNI.java,新建本地方法

public native int add(int x,int y);
public native String callformC(String s);
public native int[] intArray(int []array);
public native int checkPwd(String pwd);

在AS中ctrl +/ 可以自动生成对应的C方法

project1.png

然后就可以在生成对应的C方法中编写响应的测试逻辑
由于java的String 字符串传递过来是不能在C中直接使用,在网上找到一个把一个jstring转换成一个c语言的char* 类型的方法(原理是反射调用javad的 getByte方法)

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);
memcpy(rtn, ba, alen);
rtn[alen]=0;
}
(*env)->ReleaseByteArrayElements(env, barr, ba,0);
return rtn;
}

传递两个 int 类型数字相加返回的方法

JNIEXPORT jint JNICALLJava_com_mao_javacallc_JNI_add(JNIEnv *env, jobject instance, jint x, jint y) {   
LOGI("x+y= %d",x+y);
return x+y;
}

传入字符串拼接返回的方法

JNIEXPORT jstring JNICALLJava_com_mao_javacallc_JNI_callformC(JNIEnv *env, jobject instance, jstring s) {
char * fromjava = _JString2CStr(env,s);//调用上面的字符串转char方法将传递进来的String装换成C的char类型
char  *fromc="add from c";
//将连个字符串拼接返回给java
strcat(fromjava,fromc);//拼接好的字符串放在第一个参数里面
return (*env)->NewStringUTF(env, fromjava);
}

传入字int类型数组,数组经过处理返回int类型

JNIEXPORT jintArray JNICALLJava_com_mao_javacallc_JNI_intArray(JNIEnv *env, jobject instance, jintArray jstr) {
int length=(*env)->GetArrayLength(env,jstr);
jint *pInt = (*env)->GetIntArrayElements(env, jstr, JNI_FALSE);
int i;
for (i=0;i<length;i++){    *(pInt+i)+=10;//做位移操作}
return jstr;
}

模拟验证密码是否的方法

JNIEXPORT jint JNICALLJava_com_mao_javacallc_JNI_checkPwd(JNIEnv *env, jobject instance, jstring pwd_client) {
//将输入的密码转换成char
char *fromusr=_JString2CStr(env,pwd_client);
char * server="123";//模拟验证正确密码
//比较两个字符串是否相同
int code=strcmp(server,fromusr);
if(code==0){    
return 200;}
 else{ return 400;}
}

C中的方法写好了之后别忘了在JNI.java中添加动态链接库文件

static {    
System.loadLibrary("javacallc");
}

然后,写个简单的布局,在MainActivity中监听调用这些本地方法就可以实现对写好的C方法调用(逻辑和布局比较简单,这里就不贴了)。
最后来几张运行成功的截图:

两个数相加.png 传递字符串拼接.png 模拟密码验证.png

相关文章

  • JNI开发学习之C反射调用java方法

    前面记录了调用C的学习笔记,现在来记录一下C反射调用Java的笔记。JNI开发学习之调用C方法 Android开...

  • JNI开发学习之调用C方法

    最近接触到Android编程下的JNI开发,根据上一篇文章环境配置,下面我想通过我的学习记录一下实践笔记。 首先按...

  • JNI与底层调用1

    JNI开发系列阅读 JNI与底层调用1 JNI与底层调用2 C/C++在Android开发中的应用 1. JNI ...

  • 安卓开发通过JNI调用本地方法

    今天开发中第一次接触到对jni方法的调用,特此记录在开发踩过的坑。 java通过JNI调用c/c++编写的本地方法...

  • JNI与底层调用2

    JNI开发系列阅读 JNI与底层调用1 JNI与底层调用2 C/C++在Android开发中的应用 1. 掌握如何...

  • C/C++在Android开发中的应用

    JNI开发系列阅读 JNI与底层调用1 JNI与底层调用2 C/C++在Android开发中的应用 1. 前言 1...

  • JNI开发系列④C语言调用构造方法

    接续上篇JNI开发系列③C语言调用Java字段与方法 前情提要 Java调用C方法很简单 , 只需要编写nativ...

  • jni反射java方法

    在我们写Android代码时,调用一个类中没有公开的方法,可以进行反射调用,而JNI开发中C++调用java的方法...

  • JNI中如何调用JAVA中的类中的父类方法

    在JAVA开发和Android的JNI开发中有很多小伙伴都是只会在JAVA中调用C/C++中的方法,不知道怎么在C...

  • Android JNI学习手册

    一、JNI基础学习-JNI调用java原生方法 JNI调用java原生方法有四个重要的东西 一、class 类信息...

网友评论

    本文标题:JNI开发学习之调用C方法

    本文链接:https://www.haomeiwen.com/subject/aqlyvttx.html