tutorials.de Buch-Aktion 05/2012
ERLEDIGT
NEIN
ANTWORTEN
11
ZUGRIFFE
1809
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    raumichi raumichi ist offline Rookie
    Registriert seit
    Feb 2010
    Beiträge
    6
    Hallo,

    ich hoffe ich bin hier richtig und mir kann jemand helfen.

    Ich will einen Kartenleser ansprechen (Krankenversichertenkarte). Bei dem Kartenleser ist eine API dabei, die drei Funktionen zur Verfügung stellt:

    CT_init, CT_data und CT_close.

    Die init Funktion und die Close-Funktion laufen problemlos, nur das Aufrufen der CT_data Funktion will mir nicht gelingen.

    Definiert sind die Funktionen in der API wie folgt:

    CT_init ( unsigned short ctn , unsigned short ctn)
    CT_close ( unsigned short ctn)
    CT_data (unsigned short ctn, unsigned char *dad, unsigned char *sad,
    unsigned short lenc, unsigned char *command, unsigned short* lenr, unsigned char *response)

    Ich habe die DLL mittels JNA eingebunden und folgende Klasse definiert:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    package gbws.bw_tm.control;
     
    import java.nio.ByteBuffer;
    import com.sun.jna.Library;
    import com.sun.jna.Native;
    import com.sun.jna.ptr.ShortByReference;
     
     
    public class CtTMKartenleser {
     
       public interface IKVKarteLibrary extends Library {
          IKVKarteLibrary INSTANCE = (IKVKarteLibrary)
             Native.loadLibrary("ctdeutin" , IKVKarteLibrary.class);
        
          int CT_init(char shA, char shB);
          int CT_close(char shA);
          int CT_data(char shCtn, ByteBuffer dad, ByteBuffer sad, char shLenc, ByteBuffer sCommand, ShortByReference lenr, ByteBuffer sResponse);
       }
     
    }

    So und nun will ich die Funktionen aufrufen.

    CT_init und CT_close funktioniert, nur leider CT_data nicht.

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    
     
    final char chCtn = 0x00000001; 
             final char chPn  = 0x00000001;
                // Instanz des Kartenlesers erzeugen            
             IKVKarteLibrary lib  = IKVKarteLibrary.INSTANCE;
             // erster Schritt Kartenleser initialisieren
             int iInit = lib.CT_init(chCtn, chPn);
     
             // Datenfelder für den Zugriff auf CT_DATA #
             byte[] btDad = {1};
             byte[] btSad = {2};
             char chLenc = 0X00000005;     
             char chLenr = 256;
             short shLenr = 256;
             // Befehl
             byte[] resetICC = {0x20, 0x12, 0x01, 0x01, 0x00,0x00,  0x00, 0x00, 0x00, 0x00 };
            
            // Rückgabebereich         
             byte[] hsp = new byte[11];
             for (int i = 0; i < 10; i++) {
                hsp[i] = resetICC[i];
             }  
             byte[] rsp = new byte[501];
             for (int i = 0; i < rsp.length; i++) {
                rsp[i] = 0;
             }         
             int iErg = 0; 
                   
             
             ByteBuffer bbin  = ByteBuffer.wrap(hsp);
             ByteBuffer bbout = ByteBuffer.wrap(rsp);
             ByteBuffer bbDad = ByteBuffer.wrap(btDad);
             ByteBuffer bbSad = ByteBuffer.wrap(btSad); 
             ShortByReference p1 = new ShortByReference(); 
             p1.setValue((short)chLenr); 
     
     
             // Nun sind 4 Befehle an das Kartenterminal abzusetzen:
             iErg = lib.CT_data(chCtn , bbDad, bbSad, chLenc, bbin, p1, bbout);

    Als Rückgabewert sollte idealerweise 0 zurückkomme . ich bekomme allerdings: "202731264"

    Aus einem C++Programm, aus dem der Zugrif funktioniert, schaut das so aus:

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    int ctn=1;
    unsigned char ct_dad=1;
    unsigned char sad=2;
    unsigned short lenr=256;
    unsigned char commandcode[11];
    unsigned char responsearray[501];
    commandcode[0]=0x20;
    commandcode[1]=0x12;
    commandcode[2]=0x01;
    commandcode[3]=0x01;
    commandcode[4]=0x00;
    commandcode[5]=0x00;
    commandcode[6]=0x00;
    commandcode[7]=0x00;
    commandcode[8]=0x00;
    commandcode[9]=0x00;
    commandcode[10]=0x00;           
                
    // Request ICC zum CT schicken
    rc=CT_data(ctn,&ct_dad,&sad,5,&commandcode[0],&lenr,&responsearray[0]);


    Kann mir da jemand helfen, wo mein Denkfehler ist? Leider bin ich noch neu in JAVA und C++ kann ich kaum.

    Danke
     

  2. #2
    Avatar von miffi
    miffi miffi ist offline Mitglied Gold
    Registriert seit
    Jul 2009
    Ort
    Ravensburg (BW)
    Beiträge
    139
    Howdie.

    Prinzipiell zu JNA:
    Ich habe inzwischen einige Projekte damit durchgeführt, und solche Zahlen-Geschichten haben meistens die gleiche Ursache - Unsigned C-Variablen in signed Java-Variablen zu speichern. Vielleicht versuchst du mal den Rückgabewert im nächstgrößeren Datentyp zu speichern (in dem Fall Long), damit das Vorzeichen-Bit (das erste Bit der Variable) nicht als gesetzt interpretiert wird. Wobei es natürlich seltsam ist, dass ausgerechnet 202731264 als Ergebnis zurückkommt....

    Falls was bei der Übergabe falsch läuft:
    Versuch doch mal statt dem ByteBuffer den ByteByReference-Datentyp zu verwenden. Warum nimmst du überhaupt einen Buffer? Hast du schon mal versucht, direkt das Byte-Array zu verwenden? Das mache ich meistens bei Char-Pointern. Ich muss gestehen, mit dem ByteBuffer hab ich das noch nie ausprobiert...
    Für Mappings auf 16Bit C-Datentypen habe ich auch immer Shorts verwendet, nicht Chars. Hast du eine Möglichkeit, die Bibliothek zu debuggen und zu schauen, ob die gewünschten Werte ankommen? Dann könntest du den Fehler zumindest einschränken.

    Ohne die Bibiothek selbst zu haben kann ich dir momentan leider nur bedingt helfen.... Sorry.

    Viel Erfolg + Gruß
    miffi
     
    "A common mistake that people make when trying to design something completely foolproof is to underestimate the ingenuity of complete fools."
    Douglas Adams

  3. #3
    raumichi raumichi ist offline Rookie
    Registriert seit
    Feb 2010
    Beiträge
    6
    Hallo,

    Vielen Dank erstmal für deine Hilfe!!

    Ich hab nun die Funktion geändert:

    Code :
    1
    
    long CT_data(short shCtn, ByteBuffer dad, ByteBuffer sad, short shLenc, byte[] sCommand, Pointer lenr, byte[] sResponse);

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
             final short shCtn = 1;
             byte[] btDad = {1};
             byte[] btSad = {2};
             short shLenc = 5;     
             short shLenr = 256 ;
             final ByteBuffer bbDad = ByteBuffer.wrap(btDad);
             final ByteBuffer bbSad = ByteBuffer.wrap(btSad); 
             ShortByReference p1 = new ShortByReference(); 
             p1.setValue(shLenr); 
             Pointer pLenr = p1.getPointer();  
            
             
            
             iErg = lib.CT_data(shCtn , bbDad, bbSad, shLenc, hsp, pLenr, rsp);

    Leider mit einem ähnlichen Ergebnis: "797154176660410112".

    Debuggen kann ich die Biliothek leider nicht. Ich kann dir gerne die .dll zuschicken?
     

  4. #4
    Registriert seit
    Jun 2002
    Ort
    Saarbrücken (Saarland)
    Beiträge
    9.886
    Blog-Einträge
    29
    Hallo,

    Ich kann dir gerne die .dll zuschicken?
    Ohne das Kartenlesegerät wird das doch nichts nützen, oder?

    Gruß Tom
     
    Java rocks!
    How to become a good Java Programmer?
    Does IT in Java and .Net
    The only valid measurement of code quality: WTFs / minute
    Blog
    Xing
    Twitter

  5. #5
    raumichi raumichi ist offline Rookie
    Registriert seit
    Feb 2010
    Beiträge
    6
    Hallo,


    weiß ich nicht, ob ihr Profis damit nicht sogar was anfangen könntet.

    Ich selbst kann mit .dll und Kartenleser die Lösung nicht finden.

    Gruß


    Michi
     

  6. #6
    Avatar von miffi
    miffi miffi ist offline Mitglied Gold
    Registriert seit
    Jul 2009
    Ort
    Ravensburg (BW)
    Beiträge
    139
    Hi Michi.

    Da die Long-Variable auch mit so seltsamen Werten gefüllt wird, kommt mir eine Frage:
    Ist der Rückgabewert der Funktion CT_data nicht zufällig ein Pointer? Vielleicht liest du da grad nur Speicheradressen aus. In deinem ersten Post stehen gar keine Rückgabewerte bei der API.

    Wie Thomas schon gesagt hat - ob es sinnvoll ist, die DLL ohne Lesegerät zu testen, ist fraglich...
    Oder gibt es einen brauchbaren Rückgabewert, falls kein Lesegerät gefunden wurde? Dann könnt ich mir das schon mal anschauen.

    Gruß

    miffi
     
    "A common mistake that people make when trying to design something completely foolproof is to underestimate the ingenuity of complete fools."
    Douglas Adams

  7. #7
    raumichi raumichi ist offline Rookie
    Registriert seit
    Feb 2010
    Beiträge
    6
    Hi,

    ich bin nun total verwirrt, wenn ich es als pointer definiere kommt ein zumindest besseres Ergebnis raus. Es läuft zwar immer noch nicht korrekt, aber das Ergebnis zeigt nun eine "0" (steht eigentlich für fehlerfrei) an. Leider stehen aber keine Daten in dem Response-Bereich.

    Code :
    1
    2
    3
    4
    
     
    ShortByReference p2 = new ShortByReference(); 
    p2 = lib.CT_data(shCtn , btDad, btSad, (short) 5, hsp, p1, rsp);
    shErg = p2.getValue();

    Kann mir jemand vielleicht ein C++-Programm schreiben, dass die Funktion
    Code :
    1
    2
    
    CT_data 
    (unsigned short ctn, unsigned char * dad, unsigned char * sad, unsigned short lenc, unsigned char * command, unsigned short * lenr, unsigned char * response);
    allgemein zur Verfügung stellt und die übergebenen Bereiche an die Konsole übergibt. Dann würde ich mir ´ne .dll draus machen und schauen welcher Parameter falsch ankommt.

    Grüsse und nochmals vielen Dank!
     

  8. #8
    deepthroat deepthroat ist offline Mitglied Diamant
    tutorials.de Premium-User
    Registriert seit
    Jun 2005
    Beiträge
    8.168
    Hi.

    Laut CT-API Referenz ist der Rückgabetyp ein "signed char". (IS8)

    Man könnte schon eine C Datei erstellen welche diese Funktione zur Verfügung stellt, nur müßtest du dann auch wirklich konkret sagen wie die Funktionen aussehen (Rückgabetyp, calling convention?). Zeig mal die Headerdatei wo die Funktionen deklariert sind.

    Gruß
     
    If at first you don't succeed, try again. Then quit. No use being a damn fool about it.

  9. #9
    raumichi raumichi ist offline Rookie
    Registriert seit
    Feb 2010
    Beiträge
    6
    Hier, ich hoffe das ist die richtige:


    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    
    /*****************************************************************************
    @doc            INT EXT
    ******************************************************************************
    * $ProjectName:  $
    * $ProjectRevision:  $
    *-----------------------------------------------------------------------------
    * $Source: z:/pr/ctapi/sw/ct/rcs/ct.h $
    * $Revision: 3 $
    *-----------------------------------------------------------------------------
    * $Author: tbruendl $
    *-----------------------------------------------------------------------------
    * History: see EOF
    *-----------------------------------------------------------------------------
    *
    * Copyright © 2009 HID Global
    ******************************************************************************/
     
    #ifndef _INC_CT
       #define _INC_CT
     
    /*****************************************************************************/
    /**  CT-API return codes according CT-API 1.1                               **/
    /*****************************************************************************/
    /*
    ** @consts CT API Error Codes | The CT API functions return following error codes.
    */
    #define    OK              0           /* @cnst Function call was successful        */
    #define    ERR_INVALID    -1           /* @cnst Invalid parameter or value          */
    #define    ERR_CT         -8           /* @cnst CT error (CT not in operation)      */
    #define    ERR_TRANS      -10          /* @cnst Non-eliminable transmission error   */
    #define    ERR_MEMORY     -11          /* @cnst Memory assignment error in HTSI     */
    #define    ERR_HTSI       -128         /* @cnst HTSI error                          */
     
    #define SAD_HOST         0x02
    #define SAD_REMOTE_HOST  0x05
    #define SAD_ICC1         0x00
    #define SAD_CT           0x01
     
    #define DAD_HOST         0x02
    #define DAD_REMOTE_HOST  0x05
    #define DAD_ICC1         0x00
    #define DAD_CT           0x01
     
     
     
     
     
    #ifdef __cplusplus
        extern "C" {
    #endif
     
     
    char  _stdcall CTDEUTICM_close             (
                              unsigned short ctn
                              );
     
    char  _stdcall CTDEUTICM_init        (
                               unsigned short ctn,
                               unsigned short pn
                        );
    char _stdcall CTDEUTICM_data (
                                 unsigned short ctn,
                                 unsigned char * dad,
                                 unsigned char * sad,
                                 unsigned short lenc,
                                 unsigned char * command,
                                 unsigned short * lenr,
                                 unsigned char * response
                                 );
     
    char  _stdcall CT_close             (
                              unsigned short ctn
                              );
     
    char  _stdcall CT_init        (
                               unsigned short ctn,
                               unsigned short pn
                        );
    char  _stdcall CT_data (
                                 unsigned short ctn,
                                 unsigned char * dad,
                                 unsigned char * sad,
                                 unsigned short lenc,
                                 unsigned char * command,
                                 unsigned short * lenr,
                                 unsigned char * response
                                 );
     
     
    #ifdef __cplusplus
       }
    #endif
     
     
     
    #endif /* _INC_CT */
     

  10. #10
    deepthroat deepthroat ist offline Mitglied Diamant
    tutorials.de Premium-User
    Registriert seit
    Jun 2005
    Beiträge
    8.168
    Hi.

    Die Datei ist etwas merkwürdig. Es wird stdcall verwendet, allerdings konnte JNA die Funktionen in der DLL finden obwohl nur von Library und nicht von StdCallLibrary
    geerbt wurde... (evtl. solltest du mal StdCallLibrary versuchen...)

    Dann wird der Rückgabetyp als char spezifiziert und nicht als signed char wie laut Spezifikation.

    Außerdem wird kein declspec import bzw. export der Funktionen zur Nutzung als DLL durchgeführt. Das ist schon etwas merkwürdig.

    Ich hab mal schnell einen Testtreiber und DLL geschrieben. Wenn du die DLL erstellst mußt du die ct_EXPORTS Variable definieren - beim Kompilieren des ct_test.c Programmes nicht.

    Gruß
    Angehängte Dateien Angehängte Dateien
     
    If at first you don't succeed, try again. Then quit. No use being a damn fool about it.

  11. #11
    raumichi raumichi ist offline Rookie
    Registriert seit
    Feb 2010
    Beiträge
    6
    Hallo,


    echt super deine Hilfe

    Ich hab nun deine Sourcen kompiliert und eine .dll daraus gemacht.
    Bekomm nun aber leider beim Ausführen folgenden Fehler:

    java.lang.UnsatisfiedLinkError: Error looking up function 'CT_init': Die angegebene Prozedur wurde nicht gefunden.

    at com.sun.jna.Function.<init>(Function.java:179)


    Muss ich beim Kompilieren noch was einstellen? Ich nutze den Dev-Cpp.
     

  12. #12
    deepthroat deepthroat ist offline Mitglied Diamant
    tutorials.de Premium-User
    Registriert seit
    Jun 2005
    Beiträge
    8.168
    Hi.

    Sorry, ist mir irgendwie durch die Lappen gegangen das du hier etwas geschrieben hast. Ist das Problem denn inzwischen gelöst?
    Zitat Zitat von raumichi Beitrag anzeigen
    Ich hab nun deine Sourcen kompiliert und eine .dll daraus gemacht.
    Bekomm nun aber leider beim Ausführen folgenden Fehler:

    java.lang.UnsatisfiedLinkError: Error looking up function 'CT_init': Die angegebene Prozedur wurde nicht gefunden.

    at com.sun.jna.Function.<init>(Function.java:179)


    Muss ich beim Kompilieren noch was einstellen? Ich nutze den Dev-Cpp.
    Wie gesagt, du mußt nur die ct_EXPORTS Präprozessorvariable beim Erstellen der DLL definieren. Also -Dct_EXPORTS=1 bei den Compileroptionen in den Projekteinstellungen angeben.

    Gruß
     
    If at first you don't succeed, try again. Then quit. No use being a damn fool about it.

Ähnliche Themen

  1. Antworten: 2
    Letzter Beitrag: 18.04.10, 10:54
  2. Funktionsaufruf beim Laden einer Seite
    Von Xenolith im Forum .NET Web und Kommunikation
    Antworten: 4
    Letzter Beitrag: 09.10.08, 13:33
  3. Antworten: 4
    Letzter Beitrag: 30.07.07, 22:50
  4. Antworten: 3
    Letzter Beitrag: 03.08.06, 16:42
  5. Funktionsaufruf einer DLL mit char Parameter
    Von KaiAusDerKiste2000 im Forum C/C++
    Antworten: 2
    Letzter Beitrag: 17.06.05, 09:13