2009-05-19 9 views
0

J'essaie d'utiliser une API sous Delphi. Voici la documentation de l'APIComment appeler API avec PUCHAR?

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

Alors pucMifareKey: A pointer to the six byte Mifare key. Le code que j'ai essayé jusqu'ici;

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; 

L'erreur que je reçois est Incompatible types: 'Byte' and 'Char' à la ligne de Result:=SCardCL.... due^pointeur clé. Des idées?

+0

Vous ne créez pas de pointeur dans le code avec le caractère "^". C'est pour DE-référencement quelque chose qui est déjà un pointeur, puis il apparaît sur la droite d'un identifiant. Quand il apparaît sur la gauche, il doit précéder un nom TYPE, et qui doit apparaître dans un type ou une variable DECLARATION, comment dans une instruction exécutable. –

Répondre

1

Je ne sais pas la DLL en question, mais pour un Delphi pre 2009 I ferait ce qui suit:

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; 

La violation d'accès que vous obtenez vient probablement de la chaîne C n'étant pas terminée par 0. Utiliser une chaîne et la convertir en PChar facilitera les choses.

+0

Merci. La nouvelle fonction semble fonctionner mieux, bien que maintenant elle donne 'l'exception définie par l'application' - ce que je pense provenir de DLL due à CardHandle. Je vais tester et afficher les résultats plus tard. –

+0

Je dirais qu'il manque toujours la convention d'appel - peut-être ajouter "stdcall;" à la déclaration de fonction aide? C'est le plus probable, bien que "cdecl"; est également possible; vous devriez vérifier la documentation de l'API pour plus de détails. – mghie

+0

La documentation API doit également vous indiquer si la clé ressemble plus à une séquence de caractères ou à une séquence de nombres entiers de 8 bits - j'ai supposé la première, mais si cette dernière est vraie, utiliser PChar n'est pas vraiment correct. déclarez un type personnalisé à la place et faites pucMifareKey un pointeur vers ce type. – mghie

1

Vous ne seriez pas dans Delphi 2009? Si c'est le cas, "char" est défini comme 2 octets. Essayez plutôt "AnsiChar".

+0

Non, j'utilise Delphi 7 maintenant. –

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

Je pense que vous devez remplacer 'octet' avec 'UCHAR':

ucMifareAuthMode, ucMifareAccessType, ucMifareKeyNr: byte; 

Il est une mauvaise pratique pour traiter 'octet' comme 'char'.

+0

Merci pour le conseil, cette partie est fixée maintenant. Mais j'obtiens toujours l'erreur sur la variable de pointeur. –

+0

Tant que cela est pré Delphi 2009, il n'y a pas de différence entre l'utilisation de char ou d'octet. – mghie

1

Essayez ceci:

  1. Introduire nouveau type de tableau de UCHAR.
  2. Introduire une nouvelle variable locale de type pointeur.
  3. Définissez cette variable pour être pointeur sur votre tableau clé
  4. Utilisez ce pointeur dans la fonction appel

    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

Il donne l'erreur 'types incompatibles: char et pointer' à la touche' Pkey: =^Key; ' –

+0

Désolé. Vous avez tous les deux raison. Le code n'a pas été testé et a eu quelques erreurs stupides. Je pense (j'espère) que la version éditée est correcte. – zendar

1

Vous avez indiqué que la clé est une matrice de 6 octets (uchar). Vous déclarez un tableau dynamique à transmettre, pourquoi ne pas simplement déclarer un tableau?

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