如何用PUCHAR调用API?

时间:2009-05-19 11:39:09

标签: delphi api

我正在尝试在Delphi下使用API​​。这是API文档

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

而pucMifareKey:A pointer to the six byte Mifare key。 我到目前为止一直在尝试的代码;

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;

我得到的错误Incompatible types: 'Byte' and 'Char'位于Result:=SCardCL....到期^键指针的行。有什么想法吗?

5 个答案:

答案 0 :(得分:2)

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

我认为你应该用'UCHAR'代替'byte':

ucMifareAuthMode, ucMifareAccessType, ucMifareKeyNr: byte;

将'byte'视为'char'是一种不好的做法。

答案 1 :(得分:1)

你不会碰巧在Delphi 2009?如果是这样,“char”被定义为2个字节。请尝试“AnsiChar”。

答案 2 :(得分:1)

试试这个:

  1. 为UCHAR数组引入新类型。
  2. 引入指针类型的新局部变量。
  3. 将此变量设置为指向Key数组的指针
  4. 在函数调用中使用此指针

    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);
    

答案 3 :(得分:1)

我不知道有问题的DLL,但对于2009年之前的Delphi,我会做以下事情:

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;

您获得的访问冲突可能来自不是0终止的C字符串。使用字符串并将其转换为PChar将使事情变得更容易。

答案 4 :(得分:1)

你说密钥是一个6字节(uchar)数组。你声明一个动态数组传递,为什么不只是声明一个数组?

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