出自:http://wenku.baidu.com/link?url=X_plf2x-5OL9FOhLoGtA6JjfS5ivKKFF7m7fvwdnL0vWxi4Ulr-tZCS1UZ_ml20-sVYWwqXE4qcxAeWS7v-kCi5lpZ3ku9qxaoStoVmMeVS
JNI入门教程之HelloWorld篇
资料引用:http://www.knowsky.com/363050.html
本文讲述如何使用JNI技术实现HelloWorld,目的是让读者熟悉JNI的机制并编写第一个HelloWorld程序。
Java Native Interface(JNI)是Java语言的本地编程接口,是J2SDK的一部分。在java程序中,我们可以通过JNI实现一些用java
语言不便实现的功能。通常有以下几种情况我们需要使用JNI来实现。
标准的java类库没有提供你的应用程序所需要的功能,通常这些功能是平台相关的你希望使用一些已经有的类库或者应用程序,而他们并非用
java语言编写的程序的某些部分对速度要求比较苛刻,你选择用汇编或者c语言来实现并在java语言中调
用他们在《java核心技术》中,作者提到JNI的时候,建议不到万不得已不要使用JNI技术,一方面它需要你把握更多的知识才可以驾驭,一方面使用了
JNI你的程序就会丧失可移植性。在本文我们跳过JNI的底层机制,读者最好先把它想象为本地代码和java代码的粘合剂。关系如下图所示:
下面我们开始编写HelloWorld程序,由于涉及到要编写c/c++代码因此我们会在开发中使用Microsoft VC++工具。
编写java代码。
我们在硬盘上建立一个hello目录作为我们的工作目录,首先我们需要编写自己的java代码,在java代码中我们会声明native方法,代码非常简单。如下所示
class HelloWorld{
public native void displayHelloWorld();
static {
System.loadLibrary("hello");
}
public static void main(String[] args) {
new HelloWorld().displayHelloWorld();
}
}
注重我们的
displayHelloWorld()
方法的声明,
它有一个要害字
native
,
表明这个方法使用
java
以
外
的
语
言
实
现
。
方
法
不
包
括
实
现
,
因
为
我
们
要
用
c/c++
语
言
实
现
它
。
注
重
System.loadLibrary("hello")
这句代码,
它是在静态初始化块中定义的,
系统用来装载
hello
共
享库,这就是我们在后面生成的
hello.dll
(假如在其他的操作系统可能是其他的形式,比如
hello.so
)
编译
java
代码
javac HelloWorld.java
生成
HelloWorld.class
文件
创建
.h
文件
这一步中我们要使用
javah
命令生成
.h
文件,这个文件要在后面的
c/c++
代码中用到,我们
运行
javah
HelloWorld
。这样我们可以看到在相同目录下生成了一个
HelloWorld.h
文件,文件内
容如下
在此我们不对他进行太多的解释。
/* 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
编写本地实现代码
在这部分我们要用
C/C++
语言实现
java
中定义的方法,我们在
VC++
中新建一个
Project,
然
后创建一个
HelloWorldImp.cpp
文件,内容如下
#include <jni.h>
#include "HelloWorld.h"
#include <stdio.h>
JNIEXPORT void JNICALL
Java_HelloWorld_displayHelloWorld(JNIEnv *env, jobject obj)
{
printf("Hello world! ");
return;
}
注重我们这里
include
了
jni.h
和刚才得到的
HelloWorld.h
文件。
因此你要在
VC++
里面设置
好,
jni.h
在
JA
V
A_HOME/include
里面。编译通过后再生成
hello.dll
文件。
运行
java
程序
把
上
面
生
成
的
hello.dll
文
件
复
制
到
我
们
的
工
作
目
录
,
这
时
候
我
们
的
目
录
中
包
括
HelloWorld.java
,
HelloWorld.class
和
hello.dll
文件。运行
java HelloWorld
命令,则可在控制
台看到
Hello world
的输出了。
-
资料引用
:http://www.knowsky.com/363050.html
Java: JNI
完全手册时间
:2007-02-10 00:00:00
来源
:
作者
:
最近在公司里做了一个手机的项目,
需要
JA
V
A
程序在发送短信的时候和第三方的短信服务
器连接。
短信接口是用
C++
写的。
琢磨了三天,
大致搞懂了
JNI
的主体部分。
先将心得整理,
希望各位朋友少走弯路。
首先引用一篇文章,介绍一个简单的
JNI
的调用的过程。
JA
V
A
以其跨平台的特性深受人们喜爱,而又正由于它的跨平台的目的,使得它和本地机器
的各种内部联系变得很少,约束了它的功能。解决
JA
V
A
对本地操作的一种方法就是
JNI
。
JA
V
A
通过
JNI
调用本地方法,
而本地方法是以库文件的形式存放的
(在
WINDOWS
平台上
是
DLL
文件形式,在
UNIX
机器上是
SO
文件形式)
。通过调用本地的库文件的内部方法,
使
JA
V
A
可以实现和本地机器的紧密联系,调用系统级的各接口方法。
简单介绍及应用如下:
一、
JA
V
A
中所需要做的工作
在
JA
V
A
程序中,首先需要在类中声明所调用的库名称,如下:
static {
System.loadLibrary(“goodluck”);
}
在这里,库的扩展名字可以不用写出来,究竟是
DLL
还是
SO
,由系统自己判断。
还需对将要调用的方法做本地声明,关键字为
native
。且只需要声明,而不需要具体实现。
如下:
public native static void set(int i);
public native static int get();
然后编译该
JA
V
A
程序文件,生成
CLASS
,再用
JA
V
AH
命令,
JNI
就会生成
C/C++
的头文
件。
例如程序
testdll.java
,内容为:
public class testdll
{
static
{
System.loadLibrary("goodluck");
}
public native static int get();
public native static void set(int i);
public static void main(String[] args)
{
testdll test = new testdll();
test.set(10);
System.out.println(test.get());
}
}
用
javac testdll.java
编译它,会生成
testdll.class
。
再用
javah testdll
,
则会在当前目录下生成
testdll.h
文件,
这个文件需要被
C/C++
程序调用来
生成所需的库文件。
二、
C/C++
中所需要做的工作
对于已生成的
.h
头文件,
C/C++
所需要做的,就是把它的各个方法具体的实现。然后编译连
接成库文件即可。再把库文件拷贝到
JA
V
A
程序的路径下面,就可以用
JA
V
A
调用
C/C++
所
实现的功能了。
接上例子。我们先看一下
testdll.h
文件的内容:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class testdll */
#ifndef _Included_testdll
#define _Included_testdll
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: testdll
* Method: get
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_testdll_get (JNIEnv *, jclass);
/*
* Class: testdll