JNI学习总结之:java调用native函数以及native函数回调java类成员方法

这几天一直在摸索java的JNI特性,现在总算是阶段性地厘清了一些技术细节。


学习前请检查java环境配置,能在cmd.exe中输入java -version能显示环境信息,如:

D:\workspace>java -version
java version "1.7.0_05"
Java(TM) SE Runtime Environment (build 1.7.0_05-b05)
Java HotSpot(TM) Client VM (build 23.1-b03, mixed mode, sharing)

说明环境成功配置完成 。


1.什么是JNI

JNI是Java Native Interface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C&C++)。从Java1.1开始,JNI标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。

这段话摘自百度,意思是说,java一般是运行在JAVA虚拟机上,而虚拟机又是运行在真实机上的,为了让java可以绕过虚拟机,直接在真实机上执行二进制代码,java提供了JNI这种机制。但这种机制下编写的代码是和目标实体机平台密切相关的。所以这样的代码不能移植到其他平台上,比如在windows写的JNI程序,不能移植到linux平台,反之亦然。

2.java的代码编写

public class Test{
	public native void PrintInfo();//定义了native函数,即此函数将由其他语言编写,此源代码中只是声明即可。
	
	static{
		System.loadLibrary("test");//注意此处是static代码块,在java中,static代码块将在类加载时自动执行,System.loadLibrary函数将加载test.dll动态库,注意没有后缀
	}
	public void Callback()//此处的函数将在native函数中被调用。
	{
		System.out.println("Here is in java space,and i am function Callback");
	}

	public static void main(String[] args){
		new Test().PrintInfo();//调用native函数时,先实例化类的对象,然后在对象中调用native函数。
	}
}


代码如上,将其保存为Test.java,并在cmd窗口中执行编译命令:javac Test.java,得到Test.class文件后,然后执行头文件生成命令:javah Test,即可得到Test.h文件,此头文件将用于c代码的编写。所以可以将其路径包含进vc6的头文件路径中。

3.native的代码编写

#include "stdafx.h"
#include "test.h" //包含javah Test生成头文件,其实是声明了Java_Test_PrintInfo函数
JNIEXPORT void JNICALL Java_Test_PrintInfo(JNIEnv *env , jobject obj)//笔者的头文件中并无env,obj变量,读者自行添加
{
	WinExec("calc.exe",1);
	jclass cls=env->GetObjectClass(obj);
	jmethodID funid = env->GetMethodID(cls,"Callback","()V");
	printf("here is native space\n");
	env->CallVoidMethod(obj,funid,NULL);//调用java文件中的Callback函数
	printf("here is native space\n");
}
BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					 )
{
    return TRUE;
}

编译成test.dll后,将其移到Test.class文件的目录下。

4.最后测试

在cmd中执行java Test,效果如下:

JNI学习总结之:java调用native函数以及native函数回调java类成员方法_第1张图片



你可能感兴趣的:(JNI学习总结之:java调用native函数以及native函数回调java类成员方法)