2009-05-19 4 views
0

Ich versuche, eine API unter Delphi zu verwenden. Hier ist die API-DokumentationWie API mit PUCHAR aufrufen?

OKERR ENTRY SCardCLMifareStdAuthent 
    (IN SCARDHANDLE ulHandleCard,IN ULONG ulMifareBlockNr, 
    IN UCHAR ucMifareAuthMode,IN UCHAR ucMifareAccessType,IN UCHAR ucMifareKeyNr, 
    IN PUCHAR pucMifareKey,IN ULONG ulMifareKeyLen); 

Während pucMifareKey: A pointer to the six byte Mifare key. Der Code, den ich bisher versucht habe;

function Auth():Integer; 
type 
    TSCardCLMifareStdAuthent = function(SCARDHANDLE: cardinal; ulMifareBlockNr: ULONG; 
    ucMifareAuthMode, ucMifareAccessType, ucMifareKeyNr: byte; pucMifareKey: puchar; 
    ulMifareKeyLen: cardinal):LONG; 
var 
    SCardCLMifareStdAuthent: TSCardCLMifareStdAuthent; 
    hDLL: Integer; 
    CardHandle: cardinal; 
    i: integer; 
    Key: array of UCHAR; 
begin 
    Result:=1; 
    //CardHandle is defined here 
    SetLength(Key, 6); 
    for i := low(key) to high(key) do 
    Key[i] := $FF; 
    hDLL := LoadLibrary('scardsyn.dll'); 
    @SCardCLMifareStdAuthent := GetProcAddress(hDLL, 'SCardCLMifareStdAuthent'); 
    if @SCardCLMifareStdAuthent <> nil then 
    Result:=SCardCLMifareStdAuthent(CardHandle, $00, 96, 0, 0, ^Key, 6); 
    FreeLibrary(hDLL); 
end; 

Der Fehler ich erhalte ist Incompatible types: 'Byte' and 'Char' an der Linie von Result:=SCardCL.... aufgrund^Key-Zeiger. Irgendwelche Ideen?

+0

Sie erstellen keinen Zeiger im Code mit dem Zeichen "^". Das ist für das DE-Verweisen auf etwas, das bereits ein Zeiger ist, und dann erscheint es auf der RECHTEN Seite eines Identifikators. Wenn es auf der linken Seite angezeigt wird, muss es einem TYPE-Namen vorangestellt werden und in einem Typ oder einer Variablen DECLARATION angezeigt werden, wie in einer ausführbaren Anweisung. –

Antwort

1

ich die DLL in Frage weiß nicht, zu sein, aber für eine Delphi vor 2009 I würde Folgendes tun:

function Auth: integer; 
type 
    TSCardCLMifareStdAuthent = function(SCARDHANDLE: cardinal; 
    ulMifareBlockNr: ULONG; ucMifareAuthMode, ucMifareAccessType, 
    ucMifareKeyNr: byte; pucMifareKey: PAnsiChar; 
    ulMifareKeyLen: Cardinal): longint; 
var 
    SCardCLMifareStdAuthent: TSCardCLMifareStdAuthent; 
    hDLL: Integer; 
    CardHandle: Cardinal; 
    Key: string; 
begin 
    Result := 1; 
    //CardHandle is defined here... 
    Key := StringOfChar(Chr($FF), 6); 
    hDLL := LoadLibrary('scardsyn.dll'); 
    if hDLL <> 0 then begin 
    @SCardCLMifareStdAuthent := GetProcAddress(hDLL, 'SCardCLMifareStdAuthent'); 
    if @SCardCLMifareStdAuthent <> nil then begin 
     Result := SCardCLMifareStdAuthent(CardHandle, $00, 96, 0, 0, 
     PChar(Key), Length(Key)); 
    end; 
    FreeLibrary(hDLL); 
    end; 
end; 

Die Zugriffsverletzung erhalten Sie wahrscheinlich von der C-Zeichenfolge nicht 0-terminiert. Mit einer Saite und Casting zu PChar wird es einfacher.

+0

Danke. Die neue Funktion scheint besser zu funktionieren, obwohl es jetzt eine 'application defined exception' gibt - was meiner Ansicht nach von der DLL aufgrund von CardHandle verursacht wurde. Ich werde die Ergebnisse später testen und veröffentlichen. –

+0

Ich würde sagen, es fehlt immer noch die Aufrufkonvention - vielleicht "stdcall;" zur funktionserklärung hilft das? Es ist am wahrscheinlichsten, obwohl "cdecl;" ist auch möglich; Sie sollten die API-Dokumentation für Details überprüfen. – mghie

+0

Die API-Dokumentation sollte Ihnen auch sagen, ob der Schlüssel mehr wie eine Folge von Zeichen oder eine Sequenz von 8-Bit-Integer-Zahlen ist - ich nahm ersteres an, aber wenn letzteres wahr ist mit PChar ist nicht wirklich richtig, und Sie sollten stattdessen deklarieren Sie stattdessen einen benutzerdefinierten Typ und machen Sie pucMifareKey zu einem Zeiger auf diesen Typ. – mghie

1

Sie würden nicht in Delphi 2009 sein? Wenn dies der Fall ist, wird "char" als 2 Bytes definiert. Versuchen Sie stattdessen "AnsiChar".

+0

Nein, ich verwende gerade Delphi 7. –

2
type 
    TSCardCLMifareStdAuthent = function(SCARDHANDLE: cardinal; ulMifareBlockNr: ULONG; 
    ucMifareAuthMode, ucMifareAccessType, ucMifareKeyNr: byte; pucMifareKey: puchar; 
    ulMifareKeyLen: cardinal):LONG; 

Ich denke, Sie sollten 'byte' mit 'UCHAR' ersetzen:

ucMifareAuthMode, ucMifareAccessType, ucMifareKeyNr: byte; 

Es ist eine schlechte Praxis 'byte' als 'char' zu behandeln.

+0

Danke für den Hinweis, dieser Teil ist jetzt behoben. Aber ich bekomme immer noch Fehler auf Zeigervariable. –

+0

Solange dies vor Delphi 2009 ist, gibt es keinen Unterschied zwischen der Verwendung von char oder byte. – mghie

1

Versuchen Sie folgendes:

  1. Einführung neuer Typ für Array von UCHAR.
  2. Neue lokale Variable vom Zeigertyp einführen.
  3. diese Variable gesetzt Zeiger auf Ihrem Key Array
  4. Verwenden Sie diesen Zeiger in Funktionsaufruf

    type 
        TArrayOfUchar = array of UCHAR; 
    
    var 
        ... 
        Key : TArrayOfUchar; 
        PKey : ^TArrayOfUchar; 
    begin 
        ... 
        PKey = @Key; 
        if @SCardCLMifareStdAuthent <> nil then 
        Result:=SCardCLMifareStdAuthent(CardHandle, $00, 96, 0, 0, PKey, 6); 
    
+0

Es gibt "inkompatible Typen: char and pointer" Fehler bei 'Pkey: =^Key;' line. –

+0

Entschuldigung. Sie haben beide recht. Code wurde nicht getestet und hatte einige dumme Fehler. Ich denke (hoffe), dass die bearbeitete Version korrekt ist. – zendar

1

Sie haben angegeben, dass der Schlüssel ein 6-Byte-Array (uchar) ist. Sie deklarieren ein dynamisches Array zum Weitergeben. Warum deklarieren Sie nicht einfach ein Array?

var 
    {...} 
    MyKey: array[0..5] of UCHAR; 
begin 
    {...} 
    Result:=SCardCLMifareStdAuthent(CardHandle, $00, 96, 0, 0, @MyKey, 6); 
Verwandte Themen