java之native

本文介绍如何使用Java Native Interface (JNI)来调用本地方法,包括从Java声明native方法、生成并实现C/C++的头文件、编译为动态链接库及在Java中加载使用的过程。适用于需要访问底层系统特性、已有非Java库或优化性能的场景。
from:http://blog.youkuaiyun.com/huoshen8211/archive/2007/04/19/1570197.aspx

Java不是完美的,Java的不足除了体现在运行速度上要比传统的C++慢许多之外,Java无法直接访问到操作系统底层(如系统硬件等),为此Java使用native方法来扩展Java程序的功能。
  可以将native方法比作Java程序同C程序的接口,其实现步骤:
  1、在Java中声明native()方法,然后编译;
  2、用javah产生一个.h文件;
  3、写一个.cpp文件实现native导出方法,其中需要包含第二步产生的.h文件(注意其中又包含了JDK带的jni.h文件);
  4、将第三步的.cpp文件编译成动态链接库文件;
  5、在Java中用System.loadLibrary()方法加载第四步产生的动态链接库文件,这个native()方法就可以在Java中被访问了。

 

JAVA本地方法适用的情况

1.为了使用底层的主机平台的某个特性,而这个特性不能通过JAVA API访问

2.为了访问一个老的系统或者使用一个已有的库,而这个系统或这个库不是用JAVA编写的

3.为了加快程序的性能,而将一段时间敏感的代码作为本地方法实现。

 

首先写好JAVA文件
 /*
  * Created on 2005-12-19 Author shaoqi
  */
 package com.hode.hodeframework.modelupdate;

 public class CheckFile
 {
     public native void displayHelloWorld();

     static
     {
  System.loadLibrary("test");
     }

     public static void main(String[] args) {
        new CheckFile().displayHelloWorld();
     }
 }
然后根据写好的文件编译成CLASS文件
然后在classes或bin之类的class根目录下执行javah -jni com.hode.hodeframework.modelupdate.CheckFile,
 就会在根目录下得到一个com_hode_hodeframework_modelupdate_CheckFile.h的文件
然后根据头文件的内容编写com_hode_hodeframework_modelupdate_CheckFile.c文件
 #include "CheckFile.h"
 #include
 #include

 JNIEXPORT void JNICALL Java_com_hode_hodeframework_modelupdate_CheckFile_displayHelloWorld(JNIEnv *env, jobject obj)
 {
     printf("Hello world!/n");
     return;
 }
之后编译生成DLL文件如“test.dll”,名称与System.loadLibrary("test")中的名称一致
 vc的编译方法:cl -I%java_home%/include -I%java_home%/include/win32 -LD com_hode_hodeframework_modelupdate_CheckFile.c -Fetest.dll
最后在运行时加参数-Djava.library.path=[dll存放的路径]

 
### `native` 关键字的含义 在 Java 中,`native` 关键字用于标记一个方法为本地方法,即该方法的实现是由非 Java 语言(通常是 C 或 C++)编写的,并通过 Java Native Interface(JNI)与 Java 代码进行交互。使用 `native` 关键字声明的方法没有方法体,仅提供方法签名,其实际功能由本地代码实现。 例如: ```java public native void nativeMethod(); ``` 该声明表明 `nativeMethod()` 的实现由外部的本地库提供。调用该方法时,JVM 会通过 JNI 机制调用对应的本地函数,从而实现跨语言的交互。 ### 使用场景 `native` 方法通常用于需要与操作系统交互、进行底层硬件访问或执行性能敏感型任务的场景。常见的使用包括: - **性能优化**:对于性能要求极高的操作,如图像处理、加密算法或数学计算,可以使用 `native` 方法调用本地代码,以获得比纯 Java 更高的执行效率。 - **操作系统交互**:Java 通过 `native` 方法访问底层系统功能,如文件系统、网络接口、线程调度等。 - **硬件访问**:某些 Java 程序需要与硬件设备通信,例如传感器、打印机或嵌入式设备,这时可以通过 `native` 方法调用特定平台的驱动程序。 - **遗留系统集成**:在已有 C/C++ 代码库的基础上扩展 Java 应用,避免重复开发。 ### JNI 与本地方法调用机制 Java Native Interface(JNI)是 Java 平台提供的一组标准 API,用于实现 Java 代码与本地代码之间的交互。JNI 允许 Java 应用程序调用本地方法,同时也允许本地代码访问 Java 对象和类。 调用 `native` 方法的过程包括以下步骤: 1. **加载本地库**:通过 `System.loadLibrary()` 或 `System.load()` 加载包含本地方法实现的动态链接库。 2. **注册本地方法**:JVM 在加载类时,会查找与 `native` 方法对应的本地函数,并将其绑定到 Java 方法。 3. **执行本地代码**:当 Java 代码调用 `native` 方法时,JVM 会跳转到相应的本地函数执行。 例如: ```java public class NativeExample { public native void sayHello(); static { System.loadLibrary("nativeLib"); // 加载本地库 } public static void main(String[] args) { NativeExample example = new NativeExample(); example.sayHello(); // 调用本地方法 } } ``` 对应的 C 实现(使用 JNI 编写): ```c #include <jni.h> #include <stdio.h> #include "NativeExample.h" JNIEXPORT void JNICALL Java_NativeExample_sayHello(JNIEnv *env, jobject obj) { printf("Hello from native code!\n"); return; } ``` ### 注意事项 使用 `native` 方法时需要注意以下几点: - **可移植性**:由于 `native` 方法依赖于特定平台的实现,使用不当可能导致代码无法在不同操作系统上运行。 - **安全性**:本地代码不受 Java 安全机制的保护,可能引发内存泄漏、缓冲区溢出等安全问题。 - **调试难度**:相比 Java 代码,本地代码的调试更加复杂,需要额外的工具支持。 - **兼容性**:不同 JVM 实现对 JNI 的支持可能存在差异,需确保本地库与 JVM 版本兼容。 ### 示例代码 以下是一个完整的示例,展示如何在 Java 中声明 `native` 方法,并通过 JNI 调用 C 函数: ```java public class NativeMath { public native int add(int a, int b); static { System.loadLibrary("NativeMath"); } public static void main(String[] args) { NativeMath math = new NativeMath(); int result = math.add(5, 7); System.out.println("Result: " + result); } } ``` 对应的 C 实现: ```c #include <jni.h> #include "NativeMath.h" JNIEXPORT jint JNICALL Java_NativeMath_add(JNIEnv *env, jobject obj, jint a, jint b) { return a + b; } ``` ### 相关问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

superdont

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值