3

I have sort of action listener in ST code (similar to Pascal), where it returns me an integer. Then i have a CANopen function, which allows me to send data only in Array of bytes. How can i convert from these types?

Thanks for answer.

4 Answers 4

3

You can use the Move standard function to block-copy the integer into an array of four bytes:

var
    MyInteger: Integer;
    MyArray: array [0..3] of Byte;
begin
    // Move the integer into the array
    Move(MyInteger, MyArray, 4);

    // This may be subject to endianness, use SwapEndian (and related) as needed

    // To get the integer back from the array
    Move(MyArray, MyInteger, 4);
end;

PS: I haven't coded in Pascal for a few months now so there might be mistakes, feel free to fix.

Sign up to request clarification or add additional context in comments.

Comments

3

Here are solutions working with Free Pascal.

First, with "absolute":

var x: longint;
    a: array[1..4] of byte absolute x;

begin
x := 12345678;
writeln(a[1], ' ', a[2], ' ', a[3], ' ', a[4])
end.

With pointers:

type tarray = array[1..4] of byte;
     parray = ^tarray;

var x: longint;
    p: parray;

begin
x := 12345678;
p := parray(@x);
writeln(p^[1], ' ', p^[2], ' ', p^[3], ' ', p^[4])
end.

With binary operators:

var x: longint;

begin
x := 12345678;
writeln(x and $ff, ' ', (x shr 8) and $ff, ' ',
        (x shr 16) and $ff, ' ', (x shr 24) and $ff)
end.

With record:

type rec = record
              case kind: boolean of
              true: (int: longint);
              false: (arr: array[1..4] of byte)
           end;

var x: rec;

begin
x.int := 12345678;
writeln(x.arr[1], ' ', x.arr[2], ' ', x.arr[3], ' ', x.arr[4])
end.

Comments

2

You can also use a variant record, which is the traditional method of deliberately aliasing variables in Pascal without using pointers.

type Tselect = (selectBytes, selectInt);
type bytesInt = record
                 case Tselect of
                   selectBytes: (B : array[0..3] of byte);
                   selectInt:   (I : word);
                 end; {record}

var myBytesInt : bytesInt;

The nice thing about the variant record is that, once you set it up, you can freely access the variable in either form without having to call any conversion routines. For example "myBytesInt.I:=$1234" if you want to access it as an integer, or "myBytesInt.B[0]:=4" etc if you want you access it as a byte array.

Comments

-1

You can do something like this :

byte array[4];
int source;

array[0] = source & 0xFF000000;
array[1] = source & 0x00FF0000;
array[2] = source & 0x0000FF00;
array[3] = source & 0x000000FF;

Then if you glue array[1] to array[4] together you will get your source integer;

Edit : corrected the mask.

Edit : As Thomas pointed out in the comments -> you still have to bit shift the resulting value of ANDing to LSB to get correct values.

6 Comments

Not sure whether this C code is Pascal... Maybe #define BEGIN {?
Well I haven't used Pascal in a long time, but it can't be hard to understand this snippet and translate it back ;)
You are right about the double F's, I have corrected it. It maybe easier your way (if you could then post an example), but this was the first thing that came to mind.
You are totally right! On my defense it's saturday morning :D
You must shift, otherwise array[0], array[1] and array[2] wille be 0. Apart from that (and the fact that it's C, not Pascal), for portability, it's probably much better than playing with memory: your solution donesn't depend on endianness.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.