使用CODEsyv2.3,我尝试创建一个函数块来检查指针数据的大小,以避免在此之后写入内存的部分。
例如:
VAR_INPUT
pData: POINTER TO REAL; // Or pointer to WORD or ARRAY[1..x] ...
END_VAR
VAR_OUTPUT
DataSize: DWORD;
END_VARIF SIZEOF(pData^) <> 4 THEN
RETURN;
END_IF
DataSize := SIZEOF(pData^);现在,如果我将字节的入口放入这个块的pData中,则if仍然会签出,因为取消引用的指针似乎只返回我们所指向的大小(在本例中是真实的)。
我知道要求输入的大小是可能的,但如果输入错误或遗漏,这可能是一个潜在的问题,因为它会以其他方式扰乱程序
是否有办法检查所指向的任何数据的大小,同时避免外部输入?
发布于 2018-07-03 13:14:24
据我所知,无法检测指针的数据类型,因为它只是一个内存地址。您应该提供指针目标的大小作为其他参数,正如您所说的。只需添加一个指针不是零和大小不是零的检查,以防止(一些)问题。
其他环境的解决方案:
对于TwinCAT 3,可以使用T_Arg和helpers suchs作为F_INT来创建单输入解决方案,但我认为CODEsy2没有它们(确认任何人吗?)在该解决方案中,您必须更改函数调用,这样指针就不会成为输入。
在该解决方案中,您可以创建一个输入为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^)
);这也许是个小话题,对此很抱歉,希望它能帮助到别人。仍然希望有人能找到更好的解决方案。
编辑实际上找到了其他很好的解决方案,但我认为它也只适用于TwinCAT 3,只是想在这里发布。
通过使用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^
);发布于 2018-07-04 04:58:55
为什么需要这样的函数来检测变量大小,而这个函数已经存在了?
您所要做的就是直接在程序中调用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然后在代码中你可以
VAR
aTest: ARRAY[0..20] OF BOOL;
END_VAR
ArrSize(ADR(aTest), SIZEOF(aTest), 0);https://stackoverflow.com/questions/51151630
复制相似问题