java 本地方法的实现过程 JNI

本文介绍如何使用Java调用本地方法的过程,包括编写本地方法、使用javah工具生成头文件、用C/C++实现该方法并编译成DLL、设置环境变量及编写测试类。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

费了半天劲,终于自己实现了一个简单的java本地方法调用,这里备个份方便以后回顾。

具体步骤如下:

一:编写本地java类,该类中包含本地方法
   本地方法需要使用 native进行修饰,并且没有方法体,只有方法声明。
   本地方法可以是static或非static的。
   具体如下:

   

<span style="font-size:14px;">public class HelloNative {
	public static native void greeting();//这里使用的static,为了避免处理传输参数
  }</span>
  
二:编译该本地方法java类,这里就是HelloNative。
<span style="font-size:14px;"> javac  HelloNative.java</span>

然后得到HelloNative.class文件


三:命名你的本地java方法名:
  规则使用完整的java方法名,比如HelloNative.greeting;如果有包名则要加上包名,如com.feng.HelloNative.greeting
  然后,用_下划线替换所有的.
  如果有类名包含非ASCII码字母或数字,如'_'或者是大于'\u007F'的Unicode字符,就用_0XXXX表示,XXXX是该字母的4个十六进制数。
 
 其实你可以直接使用jdk提供的javah 工具(在JDK1.8\bin目录下),就可以实现上面的步骤。

如果你的jdk环境变量没有设置好,你可以直接通过cmd切换到该目录下,这样就可以使用该工具了。

你讲之前的HelloNative.class文件直接拷贝到在JDK1.8\bin目录下(避免设置环境变量麻烦偷笑


  --javah HelloNative(注意:这里的HelloNative是.class文件的名字
       就会生成一个该HelloNative类的头文件
       具体头文件内容如下:

 

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloNative */


#ifndef _Included_HelloNative
#define _Included_HelloNative
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     HelloNative
 * Method:    greeting
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_HelloNative_greeting
  (JNIEnv *, jclass);


#ifdef __cplusplus
}
#endif
#endif


  
  我们需要关注的是:
    JNIEXPORT void JNICALL Java_HelloNative_greeting
  (JNIEnv *, jclass);
  这对于下面用C/C++实现该方法很有帮助。



四:使用C/C++来实现该方法。
   在VS2015下创建一个Win32的动态链接库工程。
   在该工程下添加实现JNI的头文件:jni.h、jni_md.h和我们自己生成的HelloNative.h头文件
   我使用的方法是:直接把这三个头文件直接放到VS2015的Include(库)目录下。
   具体为:VS2015\VC\include这个目录。
   然后在该项目下创建一个C/C++文件:我这里创建的是HelloNative.cpp
   
   在该文件中包含jni.h和HelloNative.h头文件。
   
   并且注意把方法的原型拷贝过来:
   也就是:
   JNIEXPORT void JNICALL Java_HelloNative_greeting
  (JNIEnv *, jclass);
  
  实现这个方法:
  JNIEXPORT void JNICALL Java_HelloNative_greeting
(JNIEnv* env, jclass cl) {
printf("Hello ,Native World!");
}


最后 完整的HelloNative.cpp文件:
<span style="font-size:14px;">#include<jni.h>
#include<HelloNative.h>
JNIEXPORT void JNICALL Java_HelloNative_greeting
(JNIEnv* env, jclass cl) {

	printf("Hello ,Native World!");
}</span>

然后编译该文件,就可以得到一个动态链接库.dll文件,我们可以从VS2015中该项目的\HelloNative\x64\Debug
找到该动态链接库文件。



五:将该动态链接库文件添加到环境变量java.library.path定义的目录下,以便于被类加载器搜索到。
  可以通过:System.out.println(System.getProperty("java.library.path"));
  来查看java.library.path的内容,然后找到一个合适的目录。
  我这里选择的目录是:F:\SoftWare\LearnSoftWare\Java\JDK\JDK1.8\jre1.8\bin



六:编写测试类,进行测试:
  在使用该native方法之前,要先加载该动态链接库:
  我们使用静态代码块,它会在类被加载后,立即执行:
  
static {
		System.loadLibrary("HelloNative");//注意:HelloNative就是我们生成的包含native方法实现的动态库的名字
	}

  然后我们直接调用本地方法:
  
public static void main(String[] args) {
		HelloNative.greeting();
	}


  具体的测试代码如下:
  public class HelloNativeTest {
	public static void main(String[] args) {
		//java.library.path
//		System.out.println(System.getProperty("java.library.path"));
		HelloNative.greeting();
		
	}
	
	//现在加载动态链接库
	static {
		System.loadLibrary("HelloNative");
	}
}

到此完成 微笑


注意:一个很头疼的问题,就会我们自己实现的动态链接库必须要和jdk的版本一致
   我的是jdk64位,所以生成的动态链接库也要是64位;
   否则就会报:Can't load IA 32-bit .dll on a AMD 64-bit platform这个错误。
   
解决方法:
   在编译HelloNative.cpp之前,先进入VS2015的  ->"生成"->"配置管理器"->"活动方法平台"选择64位。
   
  然后再重新点击"生成"->"编译"。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值