欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-06-17 22:16:18
1.写Jni类 并且在下面写好需要被c调用的方法方法体也写好public class Jni { { System.loadLibrary("cCallJava"); } public native int addCallBack(); public int add(int a, int b) { Log.i("godv", "a+b = " + a + b); return a + b; }}2.利....

1.写Jni类  并且在下面写好需要被c调用的方法方法体也写好

public class Jni {

    {
        System.loadLibrary("cCallJava");
    }

    public native int addCallBack();

    public int add(int a, int b) {
        Log.i("godv", "a+b = " + a + b);
        return a + b;
    }
}

2.利用 javah 生成对应的 .h 文件 并且新建 .c 文件实现callBack方法

注意引入头文件 #include "com_godv_ccalljava_Jni.h"

获取方法签名

我这里是在如径 AndroidStudioProjects\Hello\ccalljava\build\intermediates\javac\debug\compileDebugJavaWithJavac\classes

执行  javap -s com.godv.ccalljava.Jni

方法签名如下:

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

#include "com_godv_ccalljava_Jni.h"

#include <android/log.h>
#define LOG_TAG "godv"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)

JNIEXPORT jint JNICALL Java_com_godv_ccalljava_Jni_addCallBack
  (JNIEnv * env, jobject jobj)
  {
       /**
        * 用法 :获取java类的 字节码文件
        * 参数1 :env
        * 参数2 :路径
        * 返回值 :jclass
        */
        jclass jclazz = (*env)->FindClass(env,"com/godv/ccalljava/Jni");
       /**
        * 用法 :获取java方法的 methodid
        * 参数1 :env
        * 参数2 :字节码文件
        * 参数3 :方法名
        * 参数4 :方法签名
        // AndroidStudioProjects\Hello\ccalljava\build\intermediates\javac\debug\compileDebugJavaWithJavac\classes
        * 返回值 :jmethodID
        */
       jmethodID jids = (*env)->GetMethodID(env,jclazz,"add","(II)I");
       /**
        * 用法 : 获得java类实例
        * 参数1 :env
        * 参数2 :字节码文件
        * 返回值 : jobject类型的 java实例对象
       */
       jobject jni = (*env)->AllocObject(env,jclazz);
       /**
        * 用法 : jni 调用java方法
        * 参数1 :env
        * 参数2 :java类实例
        * 参数3 : java方法ID
        * 其余参数为 该java方法所需参数
        */
       LOGD("返回值为 %d",6+7);
       return (*env)->CallIntMethod(env,jni,jids,6,7);

  }

3.在Java这面调用即可

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

注意 : 别忘了配置 ndk   配置log

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

一个c返回字符串的例子

JNIEXPORT jint JNICALL Java_com_godv_ccalljava_Jni_strCallBack
    (JNIEnv * env, jobject jobj)
    {
        jclass jclazz = (*env)->FindClass(env,"com/godv/ccalljava/Jni");
        jmethodID jids = (*env)->GetMethodID(env,jclazz,"str","(Ljava/lang/String;)V");
        jobject jni = (*env)->AllocObject(env,jclazz);
        jstring str = (**env).NewStringUTF(env,"Im godv !");
        (*env)->CallVoidMethod(env,jni,jids,str);
    }
public void str(String s) {
        Log.i("godv", "c中输入的字符串为 = " + s);
    }

一个调用静态方法的例子

JNIEXPORT void JNICALL Java_com_godv_ccalljava_Jni_staticCallBack
 (JNIEnv * env, jobject jobj)
 {
     jclass jclazz = (*env)->FindClass(env,"com/godv/ccalljava/Jni");
     jmethodID jids = (*env)->GetStaticMethodID(env,jclazz,"sta","(Ljava/lang/String;)V");
     jstring str = (**env).NewStringUTF(env,"Im static godv !");
     (*env)->CallStaticVoidMethod(env,jclazz,jids,str);
 }
public static void sta(String s) {
        Log.i("godv", "静态方法 : c中输入的字符串为 = " + s);
    }

 

本文地址:https://blog.csdn.net/we1less/article/details/108694711