Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Zugriff auf scardsyn.dll (https://www.delphipraxis.net/132694-zugriff-auf-scardsyn-dll.html)

twein 17. Apr 2009 16:53


Zugriff auf scardsyn.dll
 
Liste der Anhänge anzeigen (Anzahl: 2)
Hallo Leute,

ich versuche schon seit Tagen einen DLL-Aufruf zu realisieren.

Die Funktion die ich aufrufen will habe ich aus einem C++-HeaderFile (versucht) zu übersetzen.

<scardcl.h>

OKERR ENTRY SCardCLGetUID(
IN SCARDHANDLE ulHandleCard,
IN OUT PUCHAR pucUID,
IN ULONG ulUIDBufLen,
IN OUT PULONG pulnByteUID);

<scardcl.pas>
...

Delphi-Quellcode:
var
  SCardCLGetUID: function(ulHandleCard: SCARDHANDLE;
                          var pucUID: PUCHAR;
                          ulUIDBufLen: ULONG;
                          var pulnByteUID: PULONG): ULONG stdcall;
...

Mein Problem ist schon die Variable für "pucUID" zu generieen und zu übergeben!

Wer kann helfen????

Besten Dank
Thomas

nicodex 17. Apr 2009 17:06

Re: Zugriff auf scardsyn.dll
 
pucUID is die Adresse auf einen Byte-Buffer, dessen Länge wohl in ulUIDBufLen angegeben wird.

Wenn pucUID optional ist, dann
Delphi-Quellcode:
function SCardCLGetUID(ulHandleCard: SCARDHANDLE; pucUID: Pointer{PByte(Array)}; ulUIDBufLen: ULONG; var pulnByteUID: ULONG): OKERR; cdecl{?};
oder
Delphi-Quellcode:
function SCardCLGetUID(ulHandleCard: SCARDHANDLE; var pucUID; ulUIDBufLen: ULONG; var pulnByteUID: ULONG): OKERR; cdecl{?};

twein 17. Apr 2009 19:30

Re: Zugriff auf scardsyn.dll
 
Vielen Dank für die schnelle Antwort.

Aber leider gleiches Problem, vieleicht ist es doch nur die Variablen Declaration/Übergabe.

Denn gerade der Übergabe-Parameter (UID) wird beim Aufruf überschrieben. (Gesehen im Debugger)

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
 OkErr : ULONG;
 dwActiveProtocol : PDWord;
 ATR, UID, ReaderName : String ;
 UIDLen : ULong ;
 ATRLen : Cardinal ;
 hCard : LongInt ;
begin

 ReaderName := CB_SelReader.Text ;
 OkErr := SCardConnectA(hContext, PChar(ReaderName), SCARD_SHARE_SHARED, SCARD_PROTOCOL_T1, hCard, @dwActiveProtocol) ;
 if OkErr = 0 then begin
  ShowMessage('Connect to '+ CB_SelReader.Text ) ;
  fCardConnected := True ;

   UIDLen := 12 ;
   SetLength(UID,12 + 2) ;
   OkErr := SCardCLGetUID(hCard,Pointer(UID),12,UIDLen);
   if OkErr = 0  then begin
    // nächster Schritt
    end;

  OkErr := SCardDisconnect(hCard, SCARD_RESET_CARD) ;
  hCard := 0 ;
  fCardConnected := False ;
   If OkErr = 0 Then ShowMessage('Card has bee disconnected successfully') else ShowMessage('Error is Disconnect!') ;
 end;
end;
Besten Dank

nicodex 21. Apr 2009 08:47

Re: Zugriff auf scardsyn.dll
 
Ich habe mir das SDK von OmniKey mal kurz angesehen...

Du hast die Wahl zwischen:
Delphi-Quellcode:
function SCardCLGetUID(ulHandleCard: SCARDHANDLE; pucUID: PByte; ulUIDBufLen: ULONG; out pulnByteUID: ULONG): TOKErr; stdcall;
function SCardCLGetUID(ulHandleCard: SCARDHANDLE; pucUID: PAnsiChar; ulUIDBufLen: ULONG; out pulnByteUID: ULONG): TOKErr; stdcall;
function SCardCLGetUID(ulHandleCard: SCARDHANDLE; out pucUID; ulUIDBufLen: ULONG; out pulnByteUID: ULONG): TOKErr; stdcall;
Je nachdem, wie du pucUID lesen/verwenden willst.
(OKERR/TOKErr = LongInt und ENTRY = stdcall)

'string' ist in Delphi 2009 ein Unicode-String (zwei Byte pro Zeichen). Du solltest also eher 'AnsiString' verwenden anstatt 'string'.

Wenn du die letzte Variante verwendest (untypisierter Ausgabeparameter), dann sollte die Verwendung so aussehen
Delphi-Quellcode:
UIDLen := 12;
SetLength(UID, UIDLen);
OkErr := SCardCLGetUID(hCard, UID[1], UIDLen, UIDLen);
if OkErr = 0 then
begin
  SetLength(UID, UIDLen);
  //...
end;

twein 27. Apr 2009 14:09

Re: Zugriff auf scardsyn.dll
 
Hi,

vielen, vielen Dank für Deine fixe Antwort. (Sorry für meine lahme Antwort, war 4 Tage Ski fahren)

Ich hatte das Problem schon gelöst, gefällt mir aber nicht so gut:

Habe die betreffende Funktion in der ScardCL.pas verändert:
Delphi-Quellcode:
var
  SCardCLGetUID: function(ulHandleCard: SCARDHANDLE;
                          var pucUID ;
                          ulUIDBufLen: ULONG;
                          var pulnByteUID: ULONG) : ULONG; stdcall;
Delphi-Quellcode:
var
 OkErr : ULONG;
 dwActiveProtocol : PDWord;
 UID, ReaderName : String ;
 UID_Reader:array[0..12]of CHAR;
 UIDLen : ULong ;
 hCard : LongInt ;

begin
 ....
   UIDLen := 12 ;
   OkErr := SCardCLGetUID(hCard,UID_Reader,UIDLen,UIDLen);

Wie soll ich denn folgendes verstehen?
Zitat:

Je nachdem, wie du pucUID lesen/verwenden willst.
(OKERR/TOKErr = LongInt und ENTRY = stdcall)
Mit bestem Gruß
Thomas

nicodex 27. Apr 2009 14:17

Re: Zugriff auf scardsyn.dll
 
Zitat:

Zitat von twein
Wie soll ich denn folgendes verstehen?
Zitat:

Je nachdem, wie du pucUID lesen/verwenden willst.
(OKERR/TOKErr = LongInt und ENTRY = stdcall)

Man kann die API auf verschiedene Arten nach Delphi portieren.
So wie du es getan hast (untypisierter, erforderlicher Parameter) oder als optionalen Zeiger (x: Poiner). Das hängt aber von der API ab und wie man sie verwenden soll/darf.
Ich finde die C-Definitionen der API bereits schlecht (IN OUT und das obwohl es nur OUT ist, u.s.w).

Kurz: Es spricht nichts gegen deine Übersetzung.

twein 27. Apr 2009 14:49

Re: Zugriff auf scardsyn.dll
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hi,

nochmals Danke!

Ein ähnliches Problem habe mit der Statusabfrage eines Kartenlesegerätes "SCardGetAttrib" aus der "WinSCard.pas".

Hier der Visual-Basic Aufruf:
[visualbasic]
ATRLen = 64
OkErr = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, ATR(LBound(ATR)), ATRLen)
[/visualbasic]

Ich habe es wie folgt übersetzt!

Delphi-Quellcode:
var
 OkErr : ULONG;
 dwActiveProtocol : PDWord;
 UID, ReaderName : String ;
 UID_Reader:array[0..12]of CHAR;
 UIDLen : ULong ;
 ATR_Reader:array[0..64]of CHAR;
 ATRLen : LongInt ;
begin
 ....
  ATRLen := 64 ;
  OkErr := SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, ATR_Reader, ATRLen) ;
 ....
Oh sorry, dies ist doch kein Problem, es funktioniert!!!!

Tazidus 27. Mai 2016 16:28

AW: Zugriff auf scardsyn.dll
 
Hallo,

es ist etwas her, aber ich hoffe, dass doch noch einer hier liest.

Ich würde gerne mal wissen, wie die WinSCard.dll eingebunden wurde
und wie das Ergebnis von SCardGetAttrib ausgewertet wurde.

Irgendwie habe ich Probleme mit der Umsetzung.

In der Demo-Anwendung, die ich habe (in C++) steht folgendes:

UCHAR rgucATR[SCARD_ATR_LENGTH] = {0};
DWORD dwAtrLen = sizeof(rgucATR);
lResult = SCardGetAttrib(hCard,SCARD_ATTR_ATR_STRING,rgucATR ,&dwAtrLen);

lResult ist vom Typ LONG

Laut Microsoft ist

LONG WINAPI SCardGetAttrib(
_In_ SCARDHANDLE hCard,
_In_ DWORD dwAttrId,
_Out_ LPBYTE pbAttr,
_Inout_ LPDWORD pcbAttrLen
);

Also habe ich diese wie folgt eingebunden:

function SCardGetAttrib(hCard: LongInt; dwAttrId: DWORD; pbAttr: PByte; pcbAttrLen: DWORD): ULONG; stdcall; external 'WinSCard.dll';


Wie bekomme ich nun aus dem Wert "pbAttr" einen (sage ich mal) String.

???

Wer kann helfen.

Ich habe schon gegoogelt und gesehen, dass die Firma Advanced Card Systems Holdings Limited ein SDK und Beispiel-Code für Delphi zur Verfügung stellt. Kenn einer diesen?


Kurz gesagt, ich versuche aus einer ec-Karte die Kontodaten auszulesen.
Wer kann helfen?

hoika 27. Mai 2016 17:19

AW: Zugriff auf scardsyn.dll
 
Hallo,

var
P: PChar; // PAnsiChar, PWideChar ?
S: AnsiString;
begin
P := PChar(pbAttr);
S := StrPas(P);

Denke an die Längenbegrenzung (die Länge ist ja vorhanden)


Heiko

mkinzler 27. Mai 2016 20:18

AW: Zugriff auf scardsyn.dll
 
Wenn s vom Typ AnsiString ist, dann konsequent auch PAnsiChar verwenden.


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:47 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz