java jni 调用动态链接库dll函数

来源:互联网 发布:ubuntu安装卡在logo 编辑:程序博客网 时间:2024/05/21 13:56

各位大侠,小弟最近用java,jsp开发一个会员系统,涉及到会员卡和ic卡读写器,购买来一套设备,厂家提供了一个windows动态库文件(dll),我需要在java中调用该动态库里的函数,其实函数很简单,只有三个:一个串口初始化HANDLE ComInit(unsigned char port);一个关闭串口函数int ComClose(HANDLE icdev);还有一个读取卡号int ID_Read(HANDLE icdev,int tt,unsigned char *_Data);我尝试使用jni调用dll的方法来做,但出现c和java的类型不匹配的问题,java中无法编译和运行通过。
    不知道那位高手此前做过,小弟急需帮助,项目催的很紧啊!多谢了!

使用JNI,你在网上搜一下有很多资料。

public class testdll {
static

{
    //ic卡的函数动态库
System.loadLibrary("TF_ID");

}
public native static HANDLE ComInit(unsigned char port);

public native static int ID_Read(HANDLE icdev,int tt,unsigned char *_Data);

public native static int ComClose(HANDLE icdev);

public static void main(String[] args)

{
           testdll test = new testdll();
          //具体的调用方法
         ..................
         }
       这是那个java类,可是不能识别HANDLE,指针,以及unsigned char这样的类型,怎么办? 难道就没有高手做过这方面的东西吗? 求解答!!!

 

你可以尝试根据厂家提供的接口,自己在包装出一个符合JNI调用标准的动态链接库,然后Java程序和它进行交互,由它调用厂家提供的那个动态链接库。

你说的方法很对,但是能否具体点呢? 我的java程序应该怎么声明相应的方法呢?(是否要与dll的函数一致),另外,在你说的那个包装出的动态链接库里又怎么调用厂家那个动态链接库呢?现在就是这个具体的细节问题没办法解决,急啊!请你耐心赐教!成功了马上加分,谢谢你了

 

很感谢!但楼上所提供的方法是自己写具体的dll函数实现吧,并不是象我这样要调用读卡设备专门提供的dll,我觉得步骤是应该前面是按照jni的方法,生成了头文件h然后在c中在方法体内来调用那个设备提供的动态库dll,并调用其函数方法........
   但是我在网上没有找到这方面的例子.............

用c++写专门调用dll的一个模块,留出接口,在java中用Runtime调,试试看

“你可以尝试根据厂家提供的接口,自己在包装出一个符合JNI调用标准的动态链接库,然后Java程序和它进行交互,由它调用厂家提供的那个动态链接库。”

我想楼上的已经说得很清楚了。因为厂商的这个dll不是直接给java的,所以它不符合jni规范,所以就要求你写一个本地源程序文件,这个文件定义了符合jni规范的函数(就是带那一长串名字的函数了),再由这些函数去调厂商提供的dll文件中提供的接口。最后将你新写的这个文件编译成一个dll文件,这样在java中load你做出来的这个dll就可以了!

 

诚如你所说,你只需要3个函数,所以你要做的工作只是进行一下jni封装:)看你的提问,你还没有真正理解jni的用法

 

感谢各位给得意见,我现在已经完成了用jni标准得动态链接库(如A)得建立,然后A中来调用厂家得动态库(如B),我将生成得A考到java程序得同一目录下,执行java程序,其中包含一个可以显示调用结果得main函数,但会报一些奇怪得错误,真的不知道是什么原因,代码如下:
public class testdll {
static
{
System.loadLibrary("TF_ID");
}


public native static String ID_Read();


public static void main(String[] args)

{
testdll test = new testdll();
        String a=test.ID_Read();
        System.out.println(a);
}

}
c中调用厂家动态库得代码如下:
#include <iostream.h>
#include <windows.h>
#include <string.h>
#include <testdll.h>

typedef HANDLE (_stdcall *COMINT)(unsigned char port);
typedef int (_stdcall *COM_CLOSE)(HANDLE hr);
typedef int (_stdcall *ID_Read)(HANDLE icdev,int tt,unsigned char *_Data);


JNIEXPORT jstring JNICALL Java_testdll_ID_1Read(JNIEnv* env,jclass)
{   

HINSTANCE hTest;
HANDLE hr;
COMINT pComInit;
COM_CLOSE pComClose;
ID_Read pRead;
int j;
    unsigned char data[16]="put card on it",*A=data;
jstring jstr;

hTest=LoadLibrary("TF_ID.dll");
pComInit=(COMINT)GetProcAddress(hTest,"ComInit");
pComClose=(COM_CLOSE)GetProcAddress(hTest,"ComClose");
pRead=(ID_Read)GetProcAddress(hTest,"ID_Read");
hr=pComInit(1);
    j=pRead(hr,3000,data);

char b[16]="put card on it",*B=b;
for(int i=0;i<16;i++)   
    *(B+i)=*(A+i);
    jstr=env->NewStringUTF(b);
   
if(j==8)
return jstr;
else
return jstr;   
pComClose(hr);
FreeLibrary(hTest);

}
java程序执行得错误如下:

An unexpected exception has been detected in native code outside the VM.
Unexpected Signal : EXCEPTION_ACCESS_VIOLATION (0xc0000005) occurred at PC=0x0
Function=[Unknown.]
Library=(N/A)

NOTE: We are unable to locate the function name symbol for the error
      just occurred. Please refer to release documentation for possible
      reason and solutions.


Current Java thread:
        at testdll.ID_Read(Native Method)
        at testdll.main(testdll.java:30)

Dynamic libraries:
0x00400000 - 0x0040B000         D:\j2sdk1.4.2_08\bin\java.exe
0x77F50000 - 0x77FF7000         C:\WINDOWS\System32\ntdll.dll
0x77E40000 - 0x77F4E000         C:\WINDOWS\system32\kernel32.dll
0x77DA0000 - 0x77E3B000         C:\WINDOWS\system32\ADVAPI32.dll
0x78000000 - 0x78086000         C:\WINDOWS\system32\RPCRT4.dll
0x77BE0000 - 0x77C33000         C:\WINDOWS\system32\MSVCRT.dll
0x08000000 - 0x08138000         D:\j2sdk1.4.2_08\jre\bin\client\jvm.dll
0x77D10000 - 0x77D9C000         C:\WINDOWS\system32\USER32.dll
0x77C40000 - 0x77C80000         C:\WINDOWS\system32\GDI32.dll
0x76B10000 - 0x76B39000         C:\WINDOWS\System32\WINMM.dll
0x76300000 - 0x7631C000         C:\WINDOWS\System32\IMM32.DLL
0x62C20000 - 0x62C28000         C:\WINDOWS\System32\LPK.DLL
0x72F10000 - 0x72F6A000         C:\WINDOWS\System32\USP10.dll
0x10000000 - 0x10007000         D:\j2sdk1.4.2_08\jre\bin\hpi.dll
0x003F0000 - 0x003FE000         D:\j2sdk1.4.2_08\jre\bin\verify.dll
0x008A0000 - 0x008B9000         D:\j2sdk1.4.2_08\jre\bin\java.dll
0x008C0000 - 0x008CE000         D:\j2sdk1.4.2_08\jre\bin\zip.dll
0x02CC0000 - 0x02CF3000         D:\TF_ID.dll
0x76C60000 - 0x76C82000         C:\WINDOWS\system32\imagehlp.dll
0x6D8A0000 - 0x6D91D000         C:\WINDOWS\system32\DBGHELP.dll
0x77BD0000 - 0x77BD7000         C:\WINDOWS\system32\VERSION.dll
0x76BC0000 - 0x76BCB000         C:\WINDOWS\System32\PSAPI.DLL

Heap at VM Abort:
Heap
def new generation   total 576K, used 145K [0x10010000, 0x100b0000, 0x104f0000)

  eden space 512K,  28% used [0x10010000, 0x100346b0, 0x10090000)
  from space 64K,   0% used [0x10090000, 0x10090000, 0x100a0000)
  to   space 64K,   0% used [0x100a0000, 0x100a0000, 0x100b0000)
tenured generation   total 1408K, used 0K [0x104f0000, 0x10650000, 0x14010000)
   the space 1408K,   0% used [0x104f0000, 0x104f0000, 0x104f0200, 0x10650000)
compacting perm gen  total 4096K, used 1270K [0x14010000, 0x14410000, 0x1801000
0)
   the space 4096K,  31% used [0x14010000, 0x1414dbe8, 0x1414dc00, 0x14410000)

Local Time = Tue Nov 08 14:03:58 2005
Elapsed Time = 0
#
# The exception above was detected in native code outside the VM
#
# Java VM: Java HotSpot(TM) Client VM (1.4.2_08-b03 mixed mode)
#
# An error report file has been saved as hs_err_pid3876.log.
# Please refer to the file for further information.
#

感谢大家得关注,在大家得帮助和自己的不断尝试之下,终于解决了问题,产生刚才问题的原因是由于两个dll文件同名的问题,估计造成了dll调用自身的错误,我将封装的那个dll,即用jni方法一步一步生成出来的dll文件换了一个另外的名字,就可以了,而且必须把两个dll文件均考到java的class文件目录下来,或者将被调用的那个dll放在system32下也可以。
  问题终于解决了!!!多谢多谢!
  我知道还可以采用jacob的方式或调控件的方式来做,希望大家提出来共同研究,共同进步!