什么是JNI呢 就是 java native interface 是 sun公司提供给我们的一个可以调用本地 非 java语言代码 的接口 .
JNI技术 实现了java调用本地方法 ,但是有破坏了 java的 跨平台性 ,因为 java代码可以一次编译处处运行 但是 其他语言则不可以
还有java是强类型语言 在进行 数据的传递过程中 参数类型的不同可能会导致错误
下面一个简单的例子 实现 java调用 C语言的函数
1、首先在java中定义一个 类和 mian函数 用 native关键字 将函数 hello声明为native方法 ,不用对方法进行实现
public class NativeTest
{
public native void hello() ; //java 本地方法
public static void main(String[] args)
{
System.loadLibrary("jnicode") ; //加载动态链接库 ,注意是动态链接库的名字
NativeTest s =new NativeTest() ; //实例化类
s.hello() ; //本地方法 也就是 利用C编写的函数调用
}
}
2、 用过动态链接库的都知道在调用动态链接库的函数的时候 在库内 都有对于函数的声明 ,在JNI中 从java方法到C/C++方法 声明的一个映射 比较麻烦 因此 sun公司
提供了 一个 javah.exe的工具 可以帮助我们生成 与 java本地方法相对应的 C/C++声明
下面是 javah的用法
用法:javah [选项] <类>
其中 [选项] 包括:
-help 输出此帮助消息并退
-classpath <路径> 用于装入类的路径
-bootclasspath <路径> 用于装入引导类的路
-d <目录> 输出目录
-o <文件> 输出文件(只能使用
-jni 生成 JNI样式的头文
-version 输出版本信息
-verbose 启用详细输出
-force 始终写入输出文件
我们在使用的时候只需要 javah 类名 -jni<可以省略因为是默认参数>
这样就可以生成一个 对应的.h头文件 ,我们要把类的路径加到classpath中或者 直接进入类所在的文件夹 否则有可能找不到指定的类
我这里用到的命令是 javah me.Native.NativeTest -JNI 会生成 _NativeTest.h的头文件我这里将类放在 me.Native包中
_NativeTest.h内容
#include "jni.h"
#ifndef _Included_me_Native_NativeTest
#define _Included_me_Native_NativeTest
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT void JNICALL Java_me_Native_NativeTest_hello
(JNIEnv *, jobject);
3、 在 VS下创建一个 C/C++的空动态链接库工程 然后 追加头文件 到工程中 ,然后我们再建立一个源文件 吧 头文件中的 函数声明 拷贝到 源文件中
源文件代码
#include _me_Native_NativeTest.h" //包含生成的那个头文件
#include <iostream>
using namespace std ;
JNIEXPORT void JNICALL Java_me_Native_NativeTest_hello(JNIEnv * env, jobject obj)
{
cout<<"hello world "<<endl ;
4、完成上面的步骤还是不行 我们需要 跑到 JDK 的 安装目录下找到 JNI.H 和 WIN32文件夹下 的 jni_md 拷贝到 工程下 然后 将这2个头文件 拷贝到工程目录下
并且增加到工程中去 。。 这样才算完成了
OK 一次简单的 JNI调用 C/C++ 函数完成