JNI入门整理
来源:互联网 发布:l800清零软件中文 编辑:程序博客网 时间:2024/05/23 02:16
一.通过java代码先生成.h文件
调用带非字符类型,如整型(int),可参照下列,如为字符或字符串,阅读全文。
DOS环境下:
Java文件准备:
HelloNative.java
public class HelloNative {
public native static void greeting();
static
{
System.loadLibrary("HelloNative");
}
}
这个文件建好以后,先启动一个DOS窗口,按照下面步骤执行(注意,执行下面步骤,必须保证与Java源文件在同一目录下):
- 编译:javac HelloNative .java //生成HelloNative.class
- 生成DLL函数所需头文件(HelloNative.h):javah -jni HelloNative
HelloNative.h内容:
/* 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
测试文件:
HelloNativeTest.java
class HelloNativeTest
{public static void main(String[] args)
{
new HelloNative().greeting();
}
}
编译生成执行类文件。
创建DLL:
启动VC6.0,按以下步骤执行:
新建工程:File ---> New ---> Projects ---> Win32 Dynamic-Link Library 然后输入新建工程名称,最好是保持与要建的DLL
名字一样(这是第一次做,小心为上,随便起名,与DLL不同不知道会不会有问题,改天再试),然后选择 OK ,出现下
一个选择面板,选择 An empty dll project. ,然后直接点 Finish ,工程新建完毕。
环境准备:找到Java的安装目录下的 include目录(路径参照 D:\Program Files\Java\jdk1.6.0_20\include\ )将这个目录下的全部文件复制到VC6.0的安装目录下的 include目录下(路径参照 D:\Program Files\Microsoft Visual Studio\VC98\Include\ ),然后将D:\Program Files\Java\jdk1.6.0_20\include\ win32下的内容再复制到D:\Program Files\Microsoft Visual Studio\VC98\Include\下(这里出现了双份的jawt_md.h和jni_md.h拷贝,编译的事情,这里不具体研究,出问题再说),这些完成后,把Java代码准备时生成的DLL头文件 HelloNative.h 添加到上一步新建的DLL工程中,然后再新建一个DLL程序文件 HelloNative.c
HelloNative.c
#include "HelloNative.h"
#include <stdio.h>
JNIEXPORT void JNICALL Java_HelloNative_greeting(JNIEnv* env, jclass cl)
{
printf("Hello Native World!\n");
}
新建完成后,执行 Build ---> Build HelloNative.dll (或者按F7) 生成测试用的DLL文件
然后将DLL文件拷贝到测试用Java程序的执行类(*.class)所在文件下,这个练习是放到HelloNative.class和HelloNativeTest.class所在目录下,然后进入DOS窗口,执行 java HelloNativeTest(回车),就可以看到输出结果了。
如果是在MyEclipse工程中,需要进行下述操作:
将VC工程生成的DLL文件放到工程 bin目录下,这个练习是将 HelloNative.dll 放到 bin 目录下。
找到菜单 Run ---> Open Run Dialog... ---> Java Application(选项卡) ,在这个选项下边,会有对应于要调用DLL工程的一个选项,点进这个选项,在详细设定面板中选择 (x)=Arguments 这个选项卡,在里有一个文本输入的项目叫 VM arguments ,在里面输入 " -Djava.library.path=E:\JavaWork\nativeInterfaceCall\bin" ,然后点 Run 按钮,然后就可以执行程序了。
注意,这里的" -Djava.library.path=E:\JavaWork\nativeInterfaceCall\bin",不能在程序中用System.Setproperty()设定,因为java.library.path这个属性只在JVM启动的时候读取一次,所以,程序中的任何相关设定都是不起作用的。
HelloNative.java 这种中间类不能放在包里面,就是不能指定package。
调用带字符串参数的DLL
带字符串参数的DLL调用必须借助每三方接口,确切的说,就是在要调用的DLL上再加一层接口,下述说明参照。
上述使用例程修正如下:
HelloNative.java
public class HelloNative {
//这里对应的DLL接口定义为void greeting(char *str),这么定义是因为Java和C使用的是不同的字符集标准
//C是ANSI,Java是UTF-16(这个我也是查资料,没弄的太明白,可能有误,不过基本是这么个意思)
public native static void greeting(byte[] str,int strLength);
static
{
System.loadLibrary("HelloNative");
}
}
参照无参的HelloNative.java的说明,生成HelloNative.h头文件。
HelloNativeTest.java
class HelloNativeTest
{
public static void main(String[] args)
{
String str = new String("Hello Native World!\n");
new HelloNative().greeting(str.getBytes(),str.length());
}
}参照无参例子,新建动态链接库工程,生成DLL文件,然后将DLL放到system32下,放到别的地方也可以,不过要将你放的路径设置到系统环境变量 path 里,这样就不用运行Java的时候,总是去设定 java.library.path 这个JVM属性了。到这里,生成的是可以供windows调用的DLL。下面是参照代码:
如果是编译位于包路径下的中间件接口,使用如下格式命令
生成类文件:javac xxx.java
生成编译DLL所需头文件:javah -jni -classspath 包路径。类名(com.XXX.util.xxx)
二、另一种理解:
1.简介
JNI是Java Native Interface的缩写,它的设计目的是:
The standard Java class library may not support the platform-dependent features needed by your application.
You may already have a library or application written in another programming language and you wish to make it accessible to Java applications
You may want to implement a small portion of time-critical code in a lower-level programming language, such as assembly, and then have your Java application call these functions
2.JNI的书写步骤
编写带有native声明的方法的java类
使用javac命令编译所编写的java类
使用javah ?jni java类名生成扩展名为h的头文件
使用C/C++实现本地方法
将C/C++编写的文件生成动态连接库
ok
1) 编写java程序:
这里以HelloWorld为例。
代码1:
class HelloWorld {
public native void displayHelloWorld();
static {
System.loadLibrary("hello");
}
public static void main(String[] args) {
new HelloWorld().displayHelloWorld();
}
}
声明native方法:如果你想将一个方法做为一个本地方法的话,那么你就必须声明改方法为native的,并且不能实现。其中方法的参数和返回值在后面讲述。
Load动态库:System.loadLibrary("hello");加载动态库(我们可以这样理解:我们的方法displayHelloWorld()没有实现,但是我们在下面就直接使用了,所以必须在使用之前对它进行初始化)这里一般是以static块进行加载的。同时需要注意的是System.loadLibrary();的参数“hello”是动态库的名字。
main()方法
2) 编译没有什么好说的了
javac HelloWorld.java
3) 生成扩展名为h的头文件
javah ?jni HelloWorld
头文件的内容:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloWorld */
#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloWorld
* Method: displayHelloWorld
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
(这里我们可以这样理解:这个h文件相当于我们在java里面的接口,这里声明了一个Java_HelloWorld_displayHelloWorld (JNIEnv *, jobject);方法,然后在我们的本地方法里面实现这个方法,也就是说我们在编写C/C++程序的时候所使用的方法名必须和这里的一致)。
4) 编写本地方法
实现和由javah命令生成的头文件里面声明的方法名相同的方法。
代码2:
1 #include <jni.h>
2 #include "HelloWorld.h"
3 #include <stdio.h>
4 JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld(JNIEnv *env, jobject obj)
{
printf("Hello world!\n");
return;
}
注意代码2中的第1行,需要将jni.h(该文件可以在%JAVA_HOME%/include文件夹下面找到)文件引入,因为在程序中的JNIEnv、jobject等类型都是在该头文件中定义的;另外在第2行需要将HelloWorld.h头文件引入(我是这么理解的:相当于我们在编写java程序的时候,实现一个接口的话需要声明才可以,这里就是将HelloWorld.h头文件里面声明的方法加以实现。当然不一定是这样)。然后保存为HelloWorldImpl.c就ok了。
5) 生成动态库
这里以在Windows中为例,需要生成dll文件。在保存HelloWorldImpl.c文件夹下面,使用VC的编译器cl成。
cl -I%java_home%\include -I%java_home%\include\win32 -LD HelloWorldImp.c -Fehello.dll
注意:生成的dll文件名在选项-Fe后面配置,这里是hello,因为在HelloWorld.java文件中我们loadLibary的时候使用的名字是hello。当然这里修改之后那里也需要修改。另外需要将-I%java_home%\include -I%java_home%\include\win32参数加上,因为在第四步里面编写本地方法的时候引入了jni.h文件。
6) 运行程序
java HelloWorld就ok。^_^三、绑定VC:J
N I 调 用 动 态 库 ( . D L L ) 调 试 方 法
JNI调用DLL动态库调试方法:
1. 在myeclipse(或eclipse)项目工程里指定Native library(Build Path)到VS生成的DLL(debug生成)目录下
2.运行myeclipse下java代码,启动进程(调用DLL)
3.在VS中找到tools下的 attach to process(附加进程)
再找到该 java进程,选择attach
4.如果附加成功,则会在运行java代码(调用JNI)时进入VS调试模式
参考:http://wenku.baidu.com/view/f688068ccc22bcd126ff0c60.html
- JNI入门整理
- JNI入门
- JNI入门
- JNI入门
- JNI入门
- JNI 入门
- JNI入门
- JNI入门
- JNI入门
- JNI入门
- jni入门
- JNI入门
- JNI入门
- JNI入门
- JNI入门
- JNI入门
- jni入门
- JNI 入门
- phpcms文章发表之建表语句
- Linux 网络编程中的select
- 《和时间作朋友》读书笔记
- Java程序员的良药:应用程序的开发技巧
- 联机错误
- JNI入门整理
- Objective-C -深浅复制
- Strom配置
- linux内核的启动流程
- day14集合类,迭代器。List,列表迭代器,vector,LinkedList。Set,HashSet
- 在CHtmlView中判断页面加载完成
- Arduino OBD-II UART Adapter Library & Examples
- Integer与int的区别
- eclipse常用设置及快捷键