JNI(C/C++与java的相互调用)

java调用本地C/C++(native方法)

静态关联

package org.ngb.media;
...

static native void start(int var0); 

对应JNI方法

JNIEXPORT void JNICALL Java_org_ngb_media_MediaManager_start(JNIEnv *env,jclass cls, jint player){
    ......//逻辑代码
}

//JNIEnv *env java的环境变量,可以对java端进行操作

  JNIEnv类中有很多函数可以用:

  NewObject:创建Java类中的对象

  NewString:创建Java类中的String对象

  New<Type>Array:创建类型为Type的数组对象

  Get<Type>Field:获取类型为Type的字段

  Set<Type>Field:设置类型为Type的字段的值

  GetStatic<Type>Field:获取类型为Type的static的字段

  SetStatic<Type>Field:设置类型为Type的static的字段的值

  Call<Type>Method:调用返回类型为Type的方法

  CallStatic<Type>Method:调用返回值类型为Type的static方法

//jclass cls 代表这个本地方法的实例或者这个类本身

动态关联

原理:利用 RegisterNatives 方法来注册 java 方法与 JNI 函数的一一对应关系;

实现流程:

    1.利用结构体 JNINativeMethod 数组记录 java 方法与 JNI 函数的对应关系;
    2.实现 JNI_OnLoad 方法,在加载动态库后,执行动态注册;
    3.调用 FindClass 方法,获取 java 对象;
    4.调用 RegisterNatives 方法,传入 java 对象,以及 JNINativeMethod 数组,以及注册数目完成注册;

JNINativeMethod结构体
typedef struct {
    const char* name;
    const char* signature;
    void*       fnPtr;
} JNINativeMethod;
//第一个参数native本地方法名
//第二个参数signature描述方法参数及返回值
//第三个参数jni方法


jstring stringFromJNI(JNIEnv *env, jobject thiz){
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

static const JNINativeMethod gMethods[] = {
        {"stringFromJNI", "()Ljava/lang/String;", (jstring*)stringFromJNI}
};

JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved){

    JNIEnv* env = NULL;
    if(vm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK) //从JavaVM获取JNIEnv,一般使用1.4的版本
        return -1;
    jclass clazz = env->FindClass("com/example/efan/jni_learn2/MainActivity");
    if (!clazz){
        return -1;
    }
    if(env->RegisterNatives(clazz, gMethods, sizeof(gMethods)/sizeof(gMethods[0])))
    {
        return -1;
    }
    return JNI_VERSION_1_4;
}


C/C++调用java方法

找到方法对应的类

jclass  javaCls;

javaCls = env->FindClass("com/xxx /xxx");

获取对象实例(static 方法不用此步骤)

jmethodID mid;

mid = (*env)->GetMethodID(javaCls, "<init>", "()V");//<init> 构造方法

if(mid != 0 )
    obj = NewObject(javaCls ,mid);

获取要调用的方法的句柄

jmethodID userID = env->GetMethodID(javaCls ,"setTest" ,"(I)V"); 

调用方法

env->CallxxxMethod(obj ,userID ,参数1 ,参数2...);
发布了15 篇原创文章 · 获赞 5 · 访问量 2万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览