java JNI调用Dll动态链接库

      由于最近项目中需要读取读卡器上的信息,从来没有接触过使用java调用底层动态链接库Dll的这些东西,就到网上搜了一大堆的资料,然后慢慢摸索,学习了JNI和Jnative两种通过Java方式调用Dll文件的方法。

JNI的步骤如下:

       1.在java类中先定义了一个方法,不用实现。

	public native static int add(int a,int b);//函数声明 

 
          如果对native用法不清楚的,可以去google看看,相信就很清楚了。
       2.在java类中载入dll文件,dll文件不用扩展名,会自动识别。还有一种方法是用System.load(xxx);里面是需要绝对路径的,扩展名也不能省。

 static 
 {
   System.loadLibrary("TestDll");//载入dll
 }

     3. java类写好后用javac xxx.java进行编译
     4. 使用javah -jni xxx.生成头文件。
 第3.4点需要注意的是:一般我们都是在做项目,java类前面的包名肯定少不了,所以我们在命令行中编译时需要cd 到指定的java类路径下,例如我在Myeclipse中建立的一个工程,路径如下:D:\workspace\DiskNumber\src\com\tjn\test 先要cd

D:\workspace\DiskNumber\src\com\tjn\test 然后运行javac TestDll.java 生成class文件后,需要生成头文件,输入
set classpath=D:\workspace\DiskNumber\src ,到项目的src根目录下,然后运行javah -jni com.tjn.test.TestDll,会生成一个

com_tjn_test_TestDll.h的文件,然后改头文件的名,我这里改为TestDll.h,需要和System.loadLibrary()中的名称相对应。如果不在项目里,单个文件运行当然没问题。但是在项目中生成头文件,需要如上进行操作,否则会报找不到类的错误。

      5.可以看到生成的头文件如下:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_tjn_test_TestDll */

#ifndef _Included_com_tjn_test_TestDll
#define _Included_com_tjn_test_TestDll
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_tjn_test_TestDll
 * Method:    add
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_com_tjn_test_TestDll_add
  (JNIEnv *, jclass, jint, jint);
#ifdef __cplusplus
}
#endif
#endif

    这是javah根据java类自动生成的头文件,注释我们不管,可以看到里面的方法命名是Java_包名_类名_方法名,需要传递两个int类型的参数,在这个头文件中已经自动转换成jint类型。这个方法也没有任何的实现,相当于java中的接口,我们现在创建一个xx.c的文件来实现这里定义的方法。

JNIEXPORT jint JNICALL Java_com_tjn_test_TestDll_add
  (JNIEnv *, jclass, jint x, jint y)
{ 
	return x+y; 
} 

   如何编译生成dll,这里就不加详述了。我这个例子是用vc++6.0做的.将生成的TestDll.dll文件放置到windows/system32中,然后在java类中调用就可以啦。
       6.在java类的main函数中打印输出dll计算显示的返回结果
 

 public static void main(String[] args) { 
      int r = TestDll.add(30,20); 
      System.out.println("result = "+r); 
    } 

    这里需要注意的是由于是用javah -jni 生成的头文件包含了包名,(从头文件生成的方法名就可以看出来),将这个Java类放置到其他路径下并能调用相应的dll文件,因为该dll文件只认定那个src路径下的com.tjn.test.TestDll类。所以在其他地方或者其他工程引用的话,需要将TestDll类打成jar包,在别的工程导入这个jar包,并做如下调用:
     比如我在另外一个工程中的类main函数中调用
 

 public static void main(String[] args) { 
   int a=com.tjn.test.TestDll.add(20, 50);
   System.out.println(a);
    } 

   调用jar包里面的方法,这是这个类就还在这个com.tjn.test的路径下,所以就不会报说找不到dll的异常啦!

 

    JNative调用dll文件比JNI简单的多,改天整理后再说吧!也可以自己网上搜索,资料都差不多。

     给个参考资料http://blog.csdn.net/pengchua/archive/2008/06/11/2534842.aspx

 

   学习过程中的一些参考的相关资料:

     1. http://www.blogjava.net/orangewhy/archive/2007/05/

     2.http://www.iteye.com/topic/304594

     3.http://yinxu.iteye.com/blog/206163

     4.http://read.newbooks.com.cn/info/143806.html

 

    以上这些是我在学习JNI过程中有碰到过的问题,记录一下,做个笔记,同时如果有碰到类似问题的朋友可以和我互相交流,一起学习,进步。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值