Poprawne wykorzystanie funkcji przetwarzającej dane ze sterownika

0

Proszę o pomoc, bo nie daje rady jako początkujący

zmuszony jestem użyć tej funkcji

function TS7Helper.GetInt(pval: pointer): smallint;
Var
  BW : packed array[0..1] of byte absolute Result;
begin
  BW[0]:=pbyte(NativeInt(pval)+1)^;
  BW[1]:=pbyte(pval)^;
end;  

jako wejście do funkcji z sterownika dostaje tablice w hex Ansistring (np $3d $33)

Gdy statycznie podaje argumenty w tablicy

 a2[1]:=($3d);
 a2[2]:=($33);   

To wyliczenia zgadzją sie z sterownikiem, gdy to robię dynamicznie (a raczej próbuję) to pewnie rozbijam się o konwersję typów bo niestety funkcja nie zwraca dobrej wartości (pewnie wartość jest ok, bo robię pomyłkę w konwersji)
Proszę o pomoc w realizacji tego zadania

0
Andrzej K-a napisał(a):

jako wejście do funkcji z sterownika dostaje tablice w hex Ansistring (np $3d $33)

Dostajesz AnsiString z dwoma znakami o kodach 3D i 33, czy ciąg z siedmioma znakami o wartości $3d $33?

$3D <> '$3D'

To wyliczenia zgadzją sie z sterownikiem, gdy to robię dynamicznie (a raczej próbuję) to pewnie rozbijam się o konwersję typów bo niestety funkcja nie zwraca dobrej wartości […]

Nie zwraca dobrej, więc jaką zwraca? Podaj konkrety i kod działający nieprawidłowo, a także przykład poprawnych danych wejściowych i wyjściowych, aby było wiadomo czego oczekujesz.

0

Dostaje string z $3d $33

2

W takim razie, aby z ciągu znaków o zawartości '$3d $33' zrobić natywną liczbę, musisz skopiować dwa podciągi określające liczby i dopiero wtedy przekonwertować je na liczby. Przykład niżej:

uses
  SysUtils;

  function StringToSmallInt(APointer: Pointer): SmallInt;
  var
    ResBytes: packed array [0 .. 1] of Byte absolute Result;
    RawValue: AnsiString;
  begin
    RawValue := PAnsiChar(APointer);

    ResBytes[0] := StrToInt(Copy(RawValue, 5, 3));
    ResBytes[1] := StrToInt(Copy(RawValue, 1, 3));
  end;

var
  Value: SmallInt;
begin
  Value := StringToSmallInt(PChar('$3d $33'));
  Write('Value: ', Value);
end.

Dla nowszych Delphi i Lazarusa może wyglądać tak (z użyciem wbudowanych helperów):

uses
  SysUtils;

  function StringToSmallInt(APointer: Pointer): SmallInt;
  var
    ResBytes: packed array [0 .. 1] of Byte absolute Result;
    RawValue: AnsiString;
  begin
    RawValue := PAnsiChar(APointer);

    ResBytes[0] := RawValue.Substring(4, 3).ToInteger();
    ResBytes[1] := RawValue.Substring(0, 3).ToInteger();  // 0-based, to ci heca
  end;

W drugą stronę też nie jest zbyt trudno:

  function SmallIntToString(APointer: Pointer): AnsiString;
  var
    ValBytes: packed array [0 .. 1] of Byte; // packed opcjonalny
  begin
    ValBytes[0] := PByte(APointer + 1)^;
    ValBytes[1] := PByte(APointer + 0)^;

    Result := Format('$%2.2x $%2.2x', [ValBytes[0], ValBytes[1]]);
  end;

W przypadku braku wsparcia dużych liter dupnij sobie na koniec ToLower (lub użyj LowerCase).

Przykład działania tutaj: https://ideone.com/1g0m57

0

Dziękuję bardzo. Udało mi się rozwiązać to zadanie, ale nie tak ładnie jak Ty proponujesz. Teraz wiem jak to można zrobić w sposób "pro".
U mnie problem leżał w barku zrozumienia pascala i co trzeba zrobić. Cóż, uczymy się dalej od podstaw :)

Dzięki.

1 użytkowników online, w tym zalogowanych: 0, gości: 1