Java已经用了N年了,也知道它底层调用的是C/C++函数,也知道有JNI机制和native方法的存在。终于,昨天开始打算研究一下JNI,今天做了一个例子,这个例子是在Windows环境下运行一个具有native方法的java类。
1.创建一个InvokeNative.java文件,编辑内容如下
package com.jni;
public class InvokeNative {
static {
System.loadLibrary("invoke");
}
public native void setAge(int age);
public native static int getAge();
public static void main(String[] args) {
InvokeNative invoke = new InvokeNative();
invoke.setAge(28);
System.out.println(getAge());
}
}
将InvokeNative.java编译成java类文件
javac com/jni/InvokeNative.java
2.根据InvokeNative.class生成JNI的头文件
javah -classpath . -jni com.jni.InvokeNative
上面语句要在com目录的父目录下执行,生成出com_jni_InvokeNative.h文件,内容如下
3.写C代码并且生成动态连接库文件(动态连接库文件在linux下是.so为扩展名,在Windows下是.dll为扩展名)
生成.dll我使用的是VC6.0,当然你也可以用Visual Studio。如果没有安装,可以下载,我提供一个中文版的下载地址
http://www.cr173.com/soft/35179.html
在VC中新建一工程
看到下面界面,选择工程-->Win32 Dynamic-Link Library,填写工程名,点确定
选择创建一个简单的DLL 工程,点完成
将第2步生成的com_jni_InvokeNative.h头文件copy到F:\VSWORK\invoke目录下
选择左边的FileView工作区,打开StdAfx.h文件
注:我写错了,把invoke写成invoce了,大家用invoke就好了
在最下面添加下如代码,并保存
#include <jni.h>
#include "com_jni_InvokeNative.h"
如图
打开invoke.cpp文件,在最下面添加如下实现代码,并保存
int i = 0;
JNIEXPORT void JNICALL Java_com_jni_InvokeNative_setAge (JNIEnv *, jclass, jint j)
{
i = j;
}
JNIEXPORT jint JNICALL Java_com_jni_InvokeNative_getAge (JNIEnv *, jclass)
{
return i;
}
如下图
在VC的菜单上选择工具-->选项,打开选项对话框。添加上jdk所在文件夹下的include和include\win32文件夹。如下图
我的%JAVA_HOME%是F:\software\jdk1.6
最后生成dll文件,选择组建-->全部重建。
执行成功如下图
将VC项目Debug文件夹(我是F:\vswork\invoce\Debug)中的invoke.dll复制到C:\WINDOWS\system32目录下
5.运行InvokeNative.class就会看到调用C/C++函数成功。
java com.jni.InvokeNative
打印信息:
28
如果没有将invoke.dll复制到C:\WINDOWS\system32目录下,执行时需要指定java.library.path
java -Djava.library.path=./com/jni/ com.jni.InvokeNative