Delphi, использующий параметр указателя DLL - PullRequest
0 голосов
/ 16 октября 2019

Я работаю с DLL из RFIdeas, и в документации указано, что использование функции DLL:

short GetActiveID32(BYTE *pBuf, short wBufMaxSz)

У них нет примеров Delphi, но есть VB.NET, C # идругие. Вот выдержка для C #:

public static void getActiveID()
{
    pcproxlib.SetDevTypeSrch(PRXDEVTYP_USB);
    int rc = pcproxlib.usbConnect();
    Thread.Sleep(2500);
    if (rc == 1)
    {
        IntPtr result1 = Marshal.AllocHGlobal(32 * sizeof(int));
        byte[] arr = new byte[32];
        int nBits = pcproxlib.GetActiveID32(result1, 32);
        if(nBits == 0)
        {
            Console.WriteLine("\nNo Id Found, Please put card on the reader and make sure it must be configured with the card placed on it");
            return;
        }
        int Bytes = (nBits + 7) / 8;
        if (Bytes < 8)
        {
            Bytes = 8;
        }
        Marshal.Copy(result1, arr, 0, 32);
        String cardData = "";

        for (int i = 0; i < Bytes; i++)
        {
            String data = String.Format("{0:X2} ", arr[i]);
            cardData = data + cardData;
        }
        Console.WriteLine("\n" + nBits+"Bits" + ": " + cardData);
    }
    else
    {
        Console.WriteLine("\n Reader Not Connected");
    }
}

У меня есть следующая функция, определенная в Delphi.

function GetActiveID32( CardID : pInt; Max_Buffer_Size : integer ) : word; stdcall external 'pcProxAPI32.dll';

Я вызываю функцию так:

// Connect to USB Reader
SetConnectProduct( PRODUCT_PCPROX );
SetDevTypeSrch( PRXDEVTYP_USB );
USBDisconnect;

try
  DeviceID := 0;
  Results := GetDevCnt;
  Results := USBConnect( );
  if Results <> 0 then
  begin
    // Get Active USB reader ID
    //CardID := 0;
    repeat
      Sleep( 250 );
      Results := GetActiveID32( @CardID , 32 );
      BytesToProcess := ( Results + 7) / 8;
      if ( BytesToProcess < 8 ) then
        BytesToProcess := 8;

//    StrLCopy( BytesArray, PInt( CardID ), 32 );
//    Marshal.Copy(result1, arr, 0, 32);

      CardData := '';

      for I := 0 to Trunc( BytesToProcess ) do
      begin
        CardData := CardData + BytesArray[ i ];
      end;
    until Results > 0;

    // Disconnect from USB Reader until next needed
    USBDisconnect;
  end;
except
  on E : Exception do
  begin
    results := GetLastLibErr;
    ShowMessage( 'Error reading card ' + Results.ToString);
  end;
end;

lblCardValue.Caption := String( @CardID );

Подпись всегда мусор. Что я делаю неправильно? Я думаю, это как-то связано с моим неправильным использованием указателей.

1 Ответ

0 голосов
/ 31 октября 2019

Наконец-то у нас есть разрешение. Ниже приведен код, который работает. Надеюсь, это поможет кому-то в будущем.

     //function USBConnect( DeviceID : integer ) : SmallInt; external 'pcProxAPI32.dll';
    function USBConnect( DeviceID : integer ) : word; stdcall external 'pcProxAPI32.dll';

    // short GetActiveID32(BYTE *pBuf, short wBufMaxSz)
    function GetActiveID32( CardID : PByte; Max_Buffer_Size : word ) : word; stdcall external 'pcProxAPI32.dll';

    // BSHRT USBDisconnect(void)
    function USBDisconnect : word; stdcall external 'pcProxAPI32.dll';

var
  frmMain  : TfrmMain;
  DeviceID : integer;
  Results  : integer;
  CardInfo   : ^Byte;

const
 PRODUCT_PCPROX  : integer = 1;
 PRXDEVTYP_USB   : integer = 0;

procedure TfrmMain.btnReadCardClick(Sender: TObject);
var
  CardData       : string;

begin
  ShowMessage( 'Place card on reader' );

  // Connect to USB Reader
  SetConnectProduct( PRODUCT_PCPROX );
  SetDevTypeSrch( PRXDEVTYP_USB );
  USBDisconnect;

  try
    DeviceID := 0;
    Results := GetDevCnt;   //Only one device should be on system

    Results := USBConnect( DeviceID ); //Connect to the only device on system

    if Results <> 0 then
    begin
      repeat
        Sleep( 250 ); //Requried 250ms delay between reads
        Results := GetActiveID32( @CardInfo, 8 );
      until Results > 0;

      USBDisconnect;  // Disconnect from USB Reader until needed next

      CardData := IntToHex( Integer( Pointer( CardInfo ) ), 8 );

    end
    else
      ShowMessage( 'Unable to connect to reader' );

   except
   on E : Exception do
   begin
     results := GetLastLibErr;
     ShowMessage( 'Error reading card ' + Results.ToString);
   end;
  end;

  lblCardValue.Caption := CardData;  // Display data from card

end;

Это код, который на самом деле решил проблему.

CardData := IntToHex( Integer( Pointer( CardInfo ) ), 8 );
...