JNI查漏补缺(2)JNI动态注册

目录

一、JNI动态注册是什么?

二、JNI动态注册使用步骤

1.新增gMethods数组和JNI_OnLoad函数

2.完整HelloWorld.cpp

3.运行测试

总结


一、JNI动态注册是什么?

        静态注册的情况下,java调用的接口和jni层实现的接口有强制的一一对应关系,jni层的接口名必须是java_包名_函数名,但是动态注册情况下,jni的函数名可以自定义,然后通过数组数定义java函数名和jni函数名的对应关系。

二、JNI动态注册使用步骤

1.新增gMethods数组,JNI_OnLoad函数,修改jni接口名

//函数名从Java_HelloWorld_sayhello改为Dynamic_Java_HelloWorld_sayhello
JNIEXPORT void JNICALL Dynamic_Java_HelloWorld_sayhello
  (JNIEnv *, jobject)
{
	printf("cpp say hello world\n");
}


//gMethods定义了java接口和jni接口的对应关系
static JNINativeMethod gMethods[]=
{
	{"sayhello","()V",(void*)Dynamic_Java_HelloWorld_sayhello}
};

//JNI_OnLoad会在java层动态加载库System.loadLibrary()的时候调用
jint JNI_OnLoad(JavaVM* vm,void* reserved)
{
	JNIEnv *env=NULL;
	jint result =-1;
	if(vm->GetEnv((void**)&env,JNI_VERSION_1_4)!=JNI_OK)
	{
		return -1;
	}
    //通过反射机制找到HelloWorld类
	char className[20]={"HelloWorld"};
	jclass clazz=env->FindClass((const char*)className);
    //为HelloWorld类定义jni函数调用关系
	if(env->RegisterNatives(clazz,gMethods,1)<0)
	{
		return -1;
	}
    //默认JNI_VERSION_1_1是不支持JNI_OnLoad的,所以要返回JNI_VERSION_1_4
	result=JNI_VERSION_1_4;
	printf("JNI_ONload\n");
	return result;

}

2.完整HelloWorld.cpp

#include 
#include 
#include "HelloWorld.h"

#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     HelloWorld
 * Method:    sayhello
 * Signature: ()V
 */
JNIEXPORT void JNICALL Dynamic_Java_HelloWorld_sayhello
  (JNIEnv *, jobject)
{
	printf("cpp say hello world\n");
}


static JNINativeMethod gMethods[]=
{
	{"sayhello","()V",(void*)Dynamic_Java_HelloWorld_sayhello}
};

jint JNI_OnLoad(JavaVM* vm,void* reserved)
{
	JNIEnv *env=NULL;
	jint result =-1;
	if(vm->GetEnv((void**)&env,JNI_VERSION_1_4)!=JNI_OK)
	{
		return -1;
	}
	char className[20]={"HelloWorld"};
	jclass clazz=env->FindClass((const char*)className);
	if(env->RegisterNatives(clazz,gMethods,1)<0)
	{
		return -1;
	}

	result=JNI_VERSION_1_4;
	printf("JNI_ONload\n");
	return result;

}

#ifdef __cplusplus
}
#endif

3.运行测试

#编译
gcc HelloWorld.cpp --shared -I$JAVA_HOME/include -I$JAVA_HOME/include/linux -fPIC


#运行
java HelloWorld
#输出:
#JNI_ONload
#cpp say hello world
#call jni sayhello

总结

动态注册可以自由的定义jni接口。

你可能感兴趣的:(python,开发语言)