CoDeSys指针引用的大小

时间:2018-07-03 09:55:44

标签: pointers sizeof codesys

使用Codesys v2.3,我试图制作一个功能块来检查指针数据的大小,以免超出此范围而不会写入内存的一部分。
例如:

VAR_INPUT
    pData:        POINTER TO REAL;    // Or pointer to WORD or ARRAY[1..x] ...
END_VAR
VAR_OUTPUT
    DataSize:     DWORD;
END_VAR

IF SIZEOF(pData^) <> 4 THEN 
    RETURN;
END_IF

DataSize := SIZEOF(pData^);

现在,如果我将BYTE的地址放入该块的pData中,则IF仍将检出,因为取消引用的指针似乎只返回我们指向的大小(在这种情况下为REAL)。

我知道有可能需要输入大小,但是如果错过或输入错误,可能会出现潜在问题,因为它会以其他方式干扰程序

是否有一种方法可以检查所指向的数据的大小,同时避免外部输入?

2 个答案:

答案 0 :(得分:0)

据我所知,无法检测到指针的数据类型是什么,因为它只是一个内存地址。如您所说,您应该提供指针目标的大小作为其他参数。只需添加一个指针不为零且大小不为零的检查,以防止出现(某些)问题。


其他环境的解决方案:


对于TwinCAT 3,可以通过使用T_Arg和诸如F_INT之类的助手来创建单输入解决方案,但是我认为Codesys 2没有它们(确认有人吗?)。在该解决方案中,您必须始终更改函数调用,以使指针不会成为输入。

在该解决方案中,您可以使用输入T_Arg创建一个函数。然后通过对每个数据类型使用辅助函数来调用它。从T_Arg可以获取数据类型,大小和数据位置。

FUNCTION_BLOCK FB_Test
VAR_INPUT
    Test : T_arg;
END_VAR

Test.eType; //Data type
Test.cbLen; //Variable data length in bytes
Test.pData; //Pointer to data

并称之为:

test is an instance of FB_Test
//INT for example
//Now the cblen = 2
test(
    Test := F_INT(PointerToInt^) 
);

//REAL for example
//Now the cbLen = 4
test(
    Test := F_REAL(PointerToReal^) 
);

这也许有点题外话,对此感到抱歉,希望对您有所帮助。仍然希望有人会知道更好的解决方案。

编辑 实际上找到了其他很棒的解决方案,但我认为它也仅适用于TwinCAT3。我也想将其发布在这里。

通过使用ANY数据类型,可以提供任何内容作为参数并获取其大小。区别在于它不会接受POINTER作为输入。

FUNCTION_BLOCK FB_Test2
VAR_INPUT
    Test : ANY;
END_VAR
VAR_OUTPUT
    Size : DINT;
END_VAR
//diSize contains size of the input data type
size := Test.diSize;

用法:

//test2 is an instance of FB_Test2
//Output "Size" is 4, as this is a REAL
test2(
    Test := PointerToReal^
);

答案 1 :(得分:0)

为什么在此功能已经存在的情况下,为什么需要这种功能来检测可变大小?

您要做的就是直接在程序内部调用NewUserOperation。您不需要使用指针。据我了解,您之所以使用它们,是因为您想使输入变量具有任何类型的通用性,而不是因为您在程序中使用了指针。因此,所有原始变量都直接分配。

您的函数尝试创建SIZEOF()的环绕,而无需更改计算算法中的任何内容,然后仅使用SIZEOF(),因为这是该函数的作用。

告诉我为什么您尝试创建单独的功能,而我 会相应地更改答案。

我的假设是您需要检查变量是否是所需的大小。然后,您可以创建一个函数。

SIZEOF()

然后您可以这样称呼

FUNCTION IsSize : BOOL
    VAR_INPUT
        VarSize: INT;
        CompareTo: INT;
    END_VAR
    IsSize := (VarSize = CompareTo);
END_FUNCTION

编辑:使用数组

如果您要创建与数组一起使用的函数,并且希望能够传递无限数量的元素数组,则可以这样做。

VAR
    MyVar: REAL;
END_VAR

IF IsSize(SIZEOF(MyVAR), 4) THEN
    // DO something
END_IF

然后输入您可以的代码

FUNCTION ArrSize : BOOL
    VAR_INPUT
        MyArr: POINTER TO ARRAY[0..1000] OF BOOL;
        ArrNum: INT; (* Number of array elements *)
        ArrStart: INT; (* First index of an array *)
    END_VAR
    VAR
        iCount : INT := 0;
    END_VAR

    FOR iCount := ArrStart TO ArrNum DO
        MyArr^[iCount] := TRUE;
    END_FOR
END_FUNCTION