`
ajavafan2008
  • 浏览: 20558 次
  • 来自: ...
最近访客 更多访客>>
社区版块
存档分类
最新评论

JNI调用小结

 
阅读更多

JNI调用小结

1.简介
JNI的全称是Java Native Interface,翻译过来就是java本地接口,用来实现java与vc++/vb…之间的调用、传值。对它更多了解请参看java文档。

对于java开发人员而言,实现JNI调用简单来说基本有四步:

第一, 按照JNI调用规则写一个java类 (如XebNew.java)

第二, 使用”javac”命令编译该java类,生成class文件(XebNew.class)

第三, 使用”javah”命令生成.h文件(XebNew.h),该文件是在c(或其他)方法中的要引用到的头文件

第四, 运行调用该java类

2.示例一
下面以不带包(package)的java类的JNI调用为例简单说明

1)先写java类

public class XebNew {

static {

System.out.println(“java.library.path:”+ System.getProperty("java.library.path"));

System.loadLibrary("xebdeal");

}

public native String doXebNewId(String filePath, String id);

public static void main(String[] args) {

XebNew hh = new XebNew();

String returnStr = hh.doXebNewId( "xeb", "test");

System.out.println("result = " + returnStr);

}

}

2)编绎工程生成.class文件
3)生成.h文件
启动命令行(开始->运行 cmd.exe),从当前目录转至XebNew.class所在的目录,执行

”javah XebNew”的命令,生成” XebNew.h”的头文件(注意不要写成javah XebNew.class),这正是c++需要的头文件

生成的.h文件如下:

#include <jni.h>

/* Header for class XebNew */

#ifndef _Included_ XebNew

#define _Included_ XebNew

#ifdef __cplusplus

extern "C" {

#endif

/*

* Class: XebNew

* Method: doXebNewId

* Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;

*/

JNIEXPORT jstring JNICALL Java_ XebNew _ doXebNewId

(JNIEnv *, jobject, jstring, jstring);

#ifdef __cplusplus

}

#endif

#endif

接下来就是c 的部分了,最后要用这个头文件生成一个xebdeal的库文件。如果是在Windows平台下用,则应生成 xebdeal.dll(windows对大小写不敏感);如果是在linux平台,则应生成libxebdeal.so库文件

4)使用”java XebNew”命令运行该类

将xebdeal.dll或者libxebdeal.so加到相应”java.library.path”(此路径通过前面的XebNew类的输出语句中获得)中,使用”java XebNew”命令运行该类。注意,如果库文件存放位置不正确会产生如下错误:

Exception in thread "main" java.lang.UnsatisfiedLinkError: no xebdeal in java.library.path

at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1682)

at java.lang.Runtime.loadLibrary0(Runtime.java:822)

at java.lang.System.loadLibrary(System.java:993)

at XebNew.<clinit>(XebNew.java:9)

3.示例二
一般而言,在工程项目中,类是在某个包(package),如下:

package com.founder.mnp.domain;

/**

* 调用c方法的类

* @author chen.lm

*

*/

public class XebNew {

static {

System.out.println("java.library.path: " + System.getProperty("java.library.path"));

logger.info("java.library.path: " + System.getProperty("java.library.path"));

try{

System.loadLibrary("xebdeal");

} catch(UnsatisfiedLinkError e)

{

System.err.println( "Cannot load hello library:/n " +

e.toString() );

}

}

/**

*

* @param filePath 文件路径

* @param id

* @param keys 向文件指定位置插入的char值

* @return

*/

public native int doXebNewId(String filePath, String id, char[]keys);

}

如果用上例所说的过程来完成,则会出现如下错误:

Exception in thread "main" java.lang.UnsatisfiedLinkError: doXebNewId

at com.founder.mnp.domain.XebNew.doXebNewId(Native Method)

at com.founder.mnp.domain.XebNew.main(XebNew.java:48)

注意这个错误与上例错误的区别,原因就在于包。

如果XebNew的类在包com.founder.mnp.domain下面,那么必须到相应的class目录下面执行“javah com.founder.mnp.domain. XebNew”即可得到.h文件,文件名为:com_founder_mnp_domain_XebNew.h。

留意:如果你的class文件在目录E:/workspace/mnp21/WebRoot/WEB-INF/classes/com/founder/mnp/domain下,则黄色部分为你包名,你需要在E:/workspace/mnp21/WebRoot/WEB-INF/classes下运行“javah com.founder.mnp.domain. XebNew”命令。

剩下的就和上例一样了。

4. 小结
看完文档,应该JNI已经入了小门了,呵呵!实际可能有更复杂的情况,如生成的库文件(.dll/.so)依赖其他多个库文件。


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/icecreamchen/archive/2009/03/23/4016440.aspx

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics