看到一些面试要求都有JNI开发经验,可是工作中一直没遇到,网上JNI的学习资料很多,看似简单,可是真正写起来还是各种问题啊。现在就把学习例子的过程记录下来,用于日后参考。
1.编写java程序
package jnitest;
public class HelloWorld {
//所有native关键词修饰的都是对本地的声明
public native void displayHelloWorld();
static{
System.loadLibrary("helloQQ");//载入本地库
}
public static void main(String[] args) {
new HelloWorld().displayHelloWorld();
}
}
2.编译此程序
3.生成头文件
注意红色框中的,一定要和步骤中的包名一样,否则会报错
Exception in thread "main" java.lang.UnsatisfiedLinkError: jnitest.HelloWorld.displayHelloWorld()V
at jnitest.HelloWorld.displayHelloWorld(Native Method)
at jnitest.HelloWorld.main(HelloWorld.java:13)生成的文件jnitest_HelloWorld.h内容如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class jnitest_HelloWorld */
#ifndef _Included_jnitest_HelloWorld
#define _Included_jnitest_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: jnitest_HelloWorld
* Method: displayHelloWorld
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_jnitest_HelloWorld_displayHelloWorld
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
4. 编写本地方法实现和由javah命令生成的头文件里面声明的方法名相同的方法
打开VC,新建一个Win32 Dynamic-Link Library 的一个简单的DLL工程,名为:helloQQ。helloQQ.cpp代码如下:
#include "stdafx.h"
#include "jni.h"
#include "jnitest_HelloWorld.h"
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
JNIEXPORT void JNICALL JNICALL Java_jnitest_HelloWorld_displayHelloWorld(JNIEnv *,jobject)
{
printf("Helloworld!\n");
return;
}
其中JNIEXPORT void JNICALL JNICALL Java_jnitest_HelloWorld_displayHelloWorld(JNIEnv *,jobject)是步骤3生成头文件中的方法实现,此处就打印Helloworld! 要注意的几个地方:
1)修改设置如下:
2)引入的jni.h来自于jdk/bin/include目录,所以要把此文件添加到你的头文件夹下,同时还要引入jdk/bin/include/win32下的jawt_md.h和
jni_md.h。以及步骤3生成的头文件
3)此时如果报步骤3中的头文件中找不到jni.h,则把jni.h、jawt_md.h和jni_md.h复制到VC安装路径的VC98\Include下
jawt_md.h和
jni_md.h
jawt_md.h和
jni_md.h
jawt_md.h和jni_md.h
5.生成dll文件,ctrl+F7编译,F7组建,即可看到生成的helloQQ.dll
6.执行java文件,如下:
如果报找不到helloQQ ,则将生成的dll 文件放到System.out.println(System.getProperty("java.library.path"))打印出来的路径下,这样就应该没有问题了。