ERLEDIGT
NEIN
NEIN
ANTWORTEN
11
11
ZUGRIFFE
1809
1809
EMPFEHLEN
-
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
-
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
-
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?
-
02.03.10 09:06 #4
- Registriert seit
- Jun 2002
- Ort
- Saarbrücken (Saarland)
- Beiträge
- 9.886
- Blog-Einträge
- 29
Hallo,
Ohne das Kartenlesegerät wird das doch nichts nützen, oder?Ich kann dir gerne die .dll zuschicken?
Gruß TomJava 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
-
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
-
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
-
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
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.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);
Grüsse und nochmals vielen Dank!
-
02.03.10 14:42 #8
- 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.
-
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 */
-
02.03.10 16:03 #10
- 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ßIf at first you don't succeed, try again. Then quit. No use being a damn fool about it.
-
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.
-
26.03.10 09:17 #12
- 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?
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
-
Funktionsaufruf über dynamischen Link, Fehler: "Funktion erwartet"
Von newguy im Forum Javascript & AjaxAntworten: 2Letzter Beitrag: 18.04.10, 10:54 -
Funktionsaufruf beim Laden einer Seite
Von Xenolith im Forum .NET Web und KommunikationAntworten: 4Letzter Beitrag: 09.10.08, 13:33 -
Funktionsaufruf innerhalb einer for-Schleife t nicht :(
Von KD3 im Forum PHPAntworten: 4Letzter Beitrag: 30.07.07, 22:50 -
Funktionsaufruf einer JavaScript-Funktion in einer anderen JavaScript-Dateien
Von Greq im Forum Javascript & AjaxAntworten: 3Letzter Beitrag: 03.08.06, 16:42 -
Funktionsaufruf einer DLL mit char Parameter
Von KaiAusDerKiste2000 im Forum C/C++Antworten: 2Letzter Beitrag: 17.06.05, 09:13





Zitieren


Login





