各位大侠,小弟最近用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中无法编译和运行通过。
    不知道那位高手此前做过,小弟急需帮助,项目催的很紧啊!多谢了!

解决方案 »

  1.   

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

  2.   

    我已经查了jni的资料了,我也是按照这种方法来做的,首先用java编写一个类,类里面用System.loadLibrary方法调用动态库的名字,同时声明动态库的各个函数方法,然后就编译成class文件,再用javah生成.h文件;在c/c++中include这个头文件,生成dll,并且调用那个dll(厂家提供的)......
    现在的问题是,我在写那个java类时,需要声明那些函数方法,但是在我上面列出的函数中如HANDLE 指针和 usigned char这些类型java中都不能识别,无法编译通过,如何解决呢,多谢各位高手指教了......
      

  3.   

    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这样的类型,怎么办? 难道就没有高手做过这方面的东西吗? 求解答!!!
      

  4.   

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

  5.   

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

  6.   

    用jni可以实现,不过我觉得关键问题是:
     
    java web应用如何来调用客户端的dll?
      

  7.   

    http://blogcup.com/user1/3292/archives/2005/67365.shtml
      

  8.   

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

  9.   

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

  10.   

    在c/c++的dll里面替java作数据类型的转换
    尽量找到两者等价类型
    最差情况使用byte[],这是最原始的数据大家都能支持
    可以在java里自己实现翻译到正确类型的转换
      

  11.   

    “你可以尝试根据厂家提供的接口,自己在包装出一个符合JNI调用标准的动态链接库,然后Java程序和它进行交互,由它调用厂家提供的那个动态链接库。”我想楼上的已经说得很清楚了。因为厂商的这个dll不是直接给java的,所以它不符合jni规范,所以就要求你写一个本地源程序文件,这个文件定义了符合jni规范的函数(就是带那一长串名字的函数了),再由这些函数去调厂商提供的dll文件中提供的接口。最后将你新写的这个文件编译成一个dll文件,这样在java中load你做出来的这个dll就可以了!
      

  12.   

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

  13.   

    感谢各位给得意见,我现在已经完成了用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.DLLHeap 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.
    #
      

  14.   

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

  15.   

    希望会用jacob方式和调用控件方式来实现的朋友,能够提供这方面的资料给我,,我很希望进一步研究这方面的内容,希望得到大家的帮组,也希望与大家共同的交流,共同进步,有事情可以通过我的email跟我联系哈!
         好了,废话了这么多,该给大家发分了,可惜分数太少,又有很多朋友,所以只能平均给了,望大家谅解,下次一定多给分!!!请多多跟我联系!!