锁定老帖子 主题:JNI不完全指南
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-02-12
最后修改:2009-02-12
JNI不完全指南1. 概述JNI做为对JVM的补充,可以完成一些游离于JVM之外的代码,完成一些OS严重依赖的功能,比如你想自己实现基于IMCP的ping(如果问为什么,那么请重新学习一下IP/TCP/Socket)。 JNI包括Java代码和Native代码,所谓的native代码并非说一定是C的,即使你用其它的语言实现也可以,但是需要把它包装成操作系统特定的库,JRE中会有专门的代码去利用操作系统接口去动态加载它。 实现JNI的主体步骤如下: 1) 完成Java代码 2) 完成native代码 3) 封装native代码到系统库 4) 使用native库 2. Step By Step样例我们一步一步来实现一个基于Sun JDK的JNI的例子。其中,native代码用C来实现。而最终,这个JNI的例子将分别被部署到windows和linux上,两者有小小的区别将在后面说明。 l Java在需要使用native方法的类中,加上native的声明,然后像abstract方法一样不必给出实现。 package demo; public class HelloWorld { final static String name = "laurence"; public static String getName(){ return name; } public native String sayHello(String msg); } 很普通的Java类,注意其中的阴影部分。 l C分为两部分 1) 生成native代码的头文件 2) 实现native代码 生成native头文件javah -classpath target/classes -d . demo.HelloWorld target/classes是指定当前目录下的target/classes目录为classpath,demo.HelloWorld的class文件就在这下面 -d指输出头文件的目录,这里设为当前了 demo.HelloWorld是包含了native方法声明的Java类名
完成javah命令之后,会输出一个头文件,在本例中是demo_HelloWorld.h,代码如下: /* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class demo_HelloWorld */
#ifndef _Included_demo_HelloWorld #define _Included_demo_HelloWorld #ifdef __cplusplus extern "C" { #endif /* * Class: demo_HelloWorld * Method: sayHello * Signature: (Ljava/lang/String;)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_demo_HelloWorld_sayHello (JNIEnv *, jobject, jstring);
#ifdef __cplusplus } #endif #endif 实现native代码用C实现demo_HelloWorld.c,代码如下: #include "demo_HelloWorld.h" #include <time.h>
JNIEXPORT jstring JNICALL Java_demo_HelloWorld_sayHello(JNIEnv* env, jobject method, jstring param) { char buf[1025]; const char *pt = (*env)->GetStringUTFChars(env, param, NULL); time_t now; time(&now); strcpy(buf, pt); strcat(buf, asctime(localtime(&now))); return (*env)->NewStringUTF(env, buf); } 这个方法做的事情就是读取参数param,在后面加上个时间戳并返回新的字符串。 简单解释一下其中的关键行代码。 GetStringUTFChars是jre中提供的jni方法,用来得到java string的字符串。 NewStringUTF是jre中提供的jni方法,用来新建java string。
具体的jni方法,请参考sun的jni帮助文档和样例。 对于不同的操作系统,都有系统相关的库封装方式。在Linux上是Shared Object(.so文件),在Windows上就是Dynamic Load Library(.dll文件),其它不常用的请自行解决吧。 不需要额外的工作,直接编译成Shared Object即可。 gcc -Wall -m32 -fPIC -I/usr/java5/include -I/usr/java5/include/linux -Wl,-melf_i386 -shared -lc -Wl,--soname=hello <s
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
浏览 2379 次