Есть тестовый блок-прототип, написанный на SCL:
Code: Select all
FUNCTION Point : VOID
VAR_INPUT
    In      : BYTE;
    In_Len  : INT := 16;
    Out_Len : INT := 16;
    Val1_In : WORD := W#16#0000;
    Val2_In : WORD := W#16#0000;
    Val3_In : WORD := W#16#0000;
    Val4_In : WORD := W#16#0000;
    Val5_In : WORD := W#16#0000;
    Val6_In : WORD := W#16#0000;
    Val7_In : WORD := W#16#0000;
    Val8_In : WORD := W#16#0000;
END_VAR
VAR_OUTPUT
    Out         : BYTE;
    Val1_Out    : WORD := W#16#0000;
    Val2_Out    : WORD := W#16#0000;
    Val3_Out    : WORD := W#16#0000;
    Val4_Out    : WORD := W#16#0000;
    Val5_Out    : WORD := W#16#0000;
    Val6_Out    : WORD := W#16#0000;
    Val7_Out    : WORD := W#16#0000;
    Val8_Out    : WORD := W#16#0000;
END_VAR
VAR_TEMP
    tAny    : ANY;
    stAny AT tAny :
        STRUCT
            S7Code : BYTE;
            DataType : BYTE;
            Length : INT;
            DBNumber : INT;
            MemoryArea : BYTE;
            ByteAddressMSB : BYTE;
            ByteAddressLSB : WORD;
        END_STRUCT;
    tLenIn  : INT;
    tLenOut : INT;
    tAddr   : ARRAY[1..8] OF WORD;
    tRetVal : INT;
    tByte1  : BYTE;
    tByte2  : BYTE;
    tByte3  : BYTE;
    tByte4  : BYTE;
    tWord   : WORD;
    tInt1   : INT;
    tInt2   : INT;
    
END_VAR
BEGIN
    tLenIn := In_Len;
    IF tLenIn < 1 THEN
        tLenIn := 1;
    ELSIF tLenIn > 16 THEN
        tLenIn := 16;
    END_IF;
    tLenOut := Out_Len;
    IF tLenOut < 1 THEN
        tLenOut := 1;
    ELSIF tLenOut > 16 THEN
        tLenOut := 16;
    END_IF;
    tAny := In;
    stAny.DataType := B#16#02;
    stAny.Length := tLenIn;
    tRetVal := BLKMOV(SRCBLK :=  tAny, DSTBLK := tAddr);
  
    Val1_Out := tAddr[1];
    Val2_Out := tAddr[2];
    Val3_Out := tAddr[3];
    Val4_Out := tAddr[4];
    Val5_Out := tAddr[5];
    Val6_Out := tAddr[6];
    Val7_Out := tAddr[7];
    Val8_Out := tAddr[8];
    tAddr[1] := Val1_In;
    tAddr[2] := Val2_In;
    tAddr[3] := Val3_In;
    tAddr[4] := Val4_In;
    tAddr[5] := Val5_In;
    tAddr[6] := Val6_In;
    tAddr[7] := Val7_In;
    tAddr[8] := Val8_In;
    tAny := Out;
    tByte1 := stAny.S7Code;
    tByte2 := stAny.DataType;
    tInt1 := stAny.Length;
    tInt2 := stAny.DBNumber;
    tByte3 := stAny.MemoryArea;
    tByte4 := stAny.ByteAddressMSB;
    tWord := stAny.ByteAddressLSB;
    stAny.DataType := B#16#02;
    stAny.Length := tLenOut;
    
    tRetVal := BLKMOV(SRCBLK :=  tAddr, DSTBLK := tAny);
END_FUNCTION
Когда я в tAny беру указатель на вход In, то в структуре получаю корректные данные:
0x10 - тип ANY
0x02 - размерность BYTE
0x01 - длина
0x00 - № DB
0x81 - межзонный указатель на область I
0x0003С0 - адрес 120
Но когда очередь доходит до получения указателя на Out, то в структуре наблюдается следующее:
0x10
0x02
0x01
0x00
0x87 - межзонный указатель на область L (локальный стек блока)
0x000008 - адрес 1
Ожидалось, что последние две записи будут равны 0x82 (область Q) и 0x000500 соответственно.
В первой версии In и Out имели тип ANY и всё отлично работало, но рабочий блок будет иметь тип FB, в которых выходы не могут быть ANY.
