Я пытаюсь использовать Библиотека GlobalPlatform от Karsten Ohme (kaoh) в Delphi. Благодаря помощи некоторых людей здесь, в stackoverflow, я частично заработал, и я могу настроить подключение к кардридеру. Теперь я пытаюсь выбрать AID, и поэтому мне нужно передать AID в виде массива байтов в функцию.
Я использую исходный код GPSShell (инструмента командной строки, который использует ту же библиотеку) в качестве справочного материала, который помогает мне переводить функции. Там я нашел функцию convertStringToByteArray, которая берет строку и преобразует ее в массив байтов.
Оригинальная функция С++:
static int convertStringToByteArray(TCHAR *src, int destLength, BYTE *dest)
{
TCHAR *dummy;
unsigned int temp, i = 0;
dummy = malloc(destLength*2*sizeof(TCHAR) + sizeof(TCHAR));
_tcsncpy(dummy, src, destLength*2+1);
dummy[destLength*2] = _T('\0');
while (_stscanf(&(dummy[i*2]), _T("%02x"), &temp) > 0)
{
dest[i] = (BYTE)temp;
i++;
}
free(dummy);
return i;
}
и я попытался написать аналогичную процедуру в Delphi, я попытался преобразовать строку двумя способами - первый (буквально) преобразует каждый символ (обработанный как HEX) в целое число. Второй способ использует Move:
procedure StrToByteArray(Input: AnsiString; var Bytes: array of Byte; Literally: Boolean = false);
var
I, B : Integer;
begin
if Literally then
begin
for I := 0 to Length(Input) -1 do
if TryStrToInt('$' + Input[I +1], B) then
Bytes[I] := Byte(B)
else
Bytes[I] := Byte(0);
end else
Move(Input[1], Bytes[0], Length(Input));
end;
Но я продолжаю получать
(6A82: The application to be selected could not be found.)
ошибка, когда я пытаюсь выбрать AID
A000000003000000
Я знаю, что пытаюсь выбрать правильный AID, потому что когда я использую тот же самый AID с GPSShell, я получаю успешный ответ. Поэтому я не уверен, что проблема в моей процедуре массива String to Byte или, может быть, где-то еще.
Когда я использую точки останова и пытаюсь преобразовать строку в байты буквально, я получаю
(10, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0)
в отладчике. Но когда я пытаюсь использовать Move (или ORD), я получаю
(65, 48, 48, 48, 48, 48, 48, 48, 48, 51, 48, 48, 48, 48, 48, 48)
Я также пытался преобразовать строку в байты онлайн с различными веб-сайтами, и это дало мне другой результат.
(41, 30, 30, 30, 30, 30, 30, 30, 30, 33, 30, 30, 30, 30, 30, 30)
Итак, я немного потерялся, пытаясь выяснить, что я делаю неправильно, проблема в преобразовании моей строки в байты - или мне нужно искать где-то еще?
Исходный код C++ разбирает пары шестнадцатеричных цифр на байты:
A000000003000000
-> A0 00 00 00 03 00 00 00
Но ваш код Delphi вместо этого разбирает отдельные шестнадцатеричные цифры на байты:
A000000003000000
-> A 0 0 0 0 0 0 0 0 3 0 0 0 0 0 0
Попробуйте это вместо этого:
procedure StrToByteArray(Input: AnsiString; var Bytes: TBytes; Literally: Boolean = false);
var
I, B : Integer;
begin
if Literally then
begin
SetLength(Bytes, Length(Input) div 2);
for I := 0 to Length(Bytes)-1 do
begin
if not TryStrToInt('$' + Copy(Input, (I*2)+1, 2), B) then
B := 0;
Bytes[I] := Byte(B);
end;
end else
begin
SetLength(Bytes, Length(Input));
Move(Input[1], Bytes[0], Length(Input));
end:
end;
При этом в Delphi есть собственные функции HexToBin()
для разбора шестнадцатеричных строк в байтовые массивы. Вам не нужно писать собственный парсер, например:
procedure StrToByteArray(Input: AnsiString; var Bytes: TBytes; Literally: Boolean = false);
begin
if Literally then
begin
SetLength(Bytes, Length(Input) div 2);
HexToBin(PAnsiChar(Input), PByte(Bytes), Length(Bytes));
end else
begin
SetLength(Bytes, Length(Input));
Move(Input[1], Bytes[0], Length(Input));
end:
end;
Большое спасибо!! Это работает прямо, как и ожидалось! Вы сделали мой день! (Очередной раз)!