如何在codesys中将多个数组合并为一个数组

问题描述

我有 4 个数组,每个数组包含 10 个单词。目标是在 codesys 中将这 4 个数组合并为一个更大的数组(40 个字)。

我可以通过以下方式借助指针复制一个数组的内容

声明:

array1: ARRAY [0..9] OF WORD;
array2: ARRAY [0..9] OF WORD;
array3: ARRAY [0..9] OF WORD;
array4: ARRAY [0..9] OF WORD;
masterarray: ARRAY [0..39] OF WORD;
pt: POINTER TO ARRAY [0..39] OF WORD;

代码

pt := ADR(array1);
masterarray := pt^;

我还没想好,如何从这里继续合并其余的数组。我绑定到使用 SIZEOF 函数来计算指针的大小,并将其用作偏移量......但由于我之前没有使用过指针,我不太确定我真正应该做什么。

解决方法

你的第一选择是做简单的循环:

i,j: USINT;
len: DINT := UPPER_BOUND(array1,1); // 9 in your case
FOR i := 0 TO len DO
    masterarray[j] := array1[i];
    j := j + 1;
END_FOR
FOR i := 0 TO len DO
    masterarray[j] := array2[i];
    j := j + 1;
END_FOR
FOR i := 0 TO len DO
    masterarray[j] := array3[i];
    j := j + 1;
END_FOR
FOR i := 0 TO len DO
    masterarray[j] := array4[i];
    j := j + 1;
END_FOR

另一个选项是使用 MemoryUtils 库,特别是 MemCpy 函数:

MEMUtils.MemCpy(pbySrc := ADR(array1),pbyDest := ADR(masterarray),dwSize := SIZEOF(array1));
i := UPPER_BOUND(array1,1) + 1;
MEMUtils.MemCpy(pbySrc := ADR(array2),pbyDest := ADR(masterarray[i]),dwSize := SIZEOF(array2)); // shift the destination by i (10 in this case)
i := i + UPPER_BOUND(array2,1) + 1;
MEMUtils.MemCpy(pbySrc := ADR(array3),dwSize  := SIZEOF(array3)); // shift the destination by i (20 in this case)
i := i + UPPER_BOUND(array3,1) + 1;
MEMUtils.MemCpy(pbySrc := ADR(array4),pbyDest  := ADR(masterarray[i]),dwSize := SIZEOF(array4)); // shift the destination by i (30 in this case)

编辑:这是我写的一个小函数:

// Assume that:
//      - all ARRAYs start at index 0
//      - the destination ARRAY size can fit all source ARRAYs
//      - all ARRAYs store WORDs
FUNCTION MERGE
VAR CONSTANT
    SIZEOF_of_word: USINT := SIZEOF(WORD);
END_VAR
VAR_IN_OUT
    pointers: ARRAY [*] OF POINTER TO WORD;
    sizes: ARRAY [*] OF DWORD;
END_VAR
VAR_INPUT
    destinationPtr: POINTER TO WORD;
END_VAR
VAR
    i: DINT;
    len: DINT := UPPER_BOUND(pointers,1);
    j: DWORD;
END_VAR

FOR i := 0 TO len DO
    MEMUtils.MemCpy(pbySrc := pointers[i],pbyDest := ADR(destinationPtr[j]),dwSize := sizes[i]);
    j := j + sizes[i] / SIZEOF_of_word;
END_FOR
PROGRAM PLC_PRG
VAR
    array1: ARRAY [0..9] OF WORD := [1,2,3,4,5,6,7,8,9,10];
    array2: ARRAY [0..9] OF WORD := [11,12,13,14,15,16,17,18,19,20];
    array3: ARRAY [0..9] OF WORD := [21,22,23,24,25,26,27,28,29,30];
    array4: ARRAY [0..9] OF WORD := [31,32,33,34,35,36,37,38,39,40];
    masterarray: ARRAY [0..39] OF WORD;
    pts: ARRAY[0..3] OF POINTER TO WORD := [ADR(array1),ADR(array2),ADR(array3),ADR(array4)];
    ss: ARRAY[0..3] OF DWORD := [SIZEOF(array1),SIZEOF(array2),SIZEOF(array3),SIZEOF(array4)];
END_VAR

MERGE(pointers := pts,sizes := ss,destinationPtr := ADR(masterarray));

PS:我不知道这是否是最有效的方法