JNI初步(一)java调用c方法

本例子基于上一篇配置成功后进行简单的函数调用 还未配置成功参照如下链接配置

https://blog.csdn.net/we1less/article/details/108685734

1.创建jni类 加载动态库

public class Jni {
    {
        System.loadLibrary("javaCallc");
    }

    //调用c代码实现加法运算
    public native int add(int a,int b);

}

2.利用终端cd到       AndroidStudioProjects\项目名\javacallc\src\main\java     路径  

执行代码 

javah com.godv.javacallc.Jni

此时会生成一个对应的 .h头文件

3.依据 头文件写 .c文件     这里由于  int类型在三方中是通用的 所以直接进行加法返回

#include "com_godv_javacallc_Jni.h"

jint Java_com_godv_javacallc_Jni_add
(JNIEnv * env, jobject jobj, jint ja, jint jb)
{
    return ja + jb;
}

4.在app下的build.gradle文件中配置动态库的名字

-->android-->defaultConfig-->

 ndk{
            moduleName "javaCallc"  //so   文件   lib+moduleName+.so
            abiFilters 'armeabi' , 'armeabi','x86', 'armeabi-v7a', 'x86_64', 'arm64-v8a' //cpu类型
        }

5.new 相应对象使用

private Jni jni;

public void add(View view) {
        int result = jni.add(7, 9);
        Log.i("godv", result + "");
    }

返回String 类型

首先更新一个c语言的代码   把一个jstring转换成一个c语言的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;
}

impl的gerString实现       引入头文件

#include<string.h>
JNIEXPORT jstring JNICALL Java_com_godv_javacallc_Jni_getString
  (JNIEnv * env , jobject jobj , jstring jstr)
  {
       char * java = _JString2CStr(env,jstr);
       char * c = " godb godc";
       strcat(java,c);
       return (* env)->NewStringUTF(env,java);
  }

 impl的setArray实现 

JNIEXPORT void JNICALL Java_com_godv_javacallc_Jni_setArray
  (JNIEnv * env, jobject jobj, jintArray jarr)
  {
       //得到jarr的长度
       int len = (*env)->GetArrayLength(env,jarr);
       //得到jarrd的头指针
       jint * arr = (*env)->GetIntArrayElements(env,jarr,JNI_FALSE);
       int i;
       for(i= 0;i<len ;i++)
       {
           *(arr+i)+=10;
       }
       //修改后再调用SetXXArrayRegion方法提交到Java数组里面(如果不提交的话,不会修改Java数组元素的值)
       (*env)->SetIntArrayRegion(env, jarr, 0,len,arr);
  }

  impl的check实现 

JNIEXPORT jboolean JNICALL Java_com_godv_javacallc_Jni_checkPwd
  (JNIEnv * env, jobject jobj, jstring jstr)
  {
      char * java = _JString2CStr(env,jstr);
      char * pwd = "123456";
      return strcmp(java,pwd)== 0 ? JNI_TRUE:JNI_FALSE;
  }

猜你喜欢

转载自blog.csdn.net/we1less/article/details/108691477