Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Pointers CoDeSys指针引用的大小_Pointers_Sizeof_Codesys - Fatal编程技术网

Pointers CoDeSys指针引用的大小

Pointers CoDeSys指针引用的大小,pointers,sizeof,codesys,Pointers,Sizeof,Codesys,使用Codesys v2.3,我试图创建一个功能块,用于检查指针数据的大小,以避免写入超出此范围的部分内存。 例: 如果SIZEOF(pData^)4那么 回来 结束(如有) 数据大小:=SIZEOF(pData^); 现在,如果我将一个字节的地址放入这个块的pData中,if仍然会检查出来,因为解引用指针似乎只返回我们所指向的大小(在本例中为实) 我知道可能需要输入大小,但如果丢失或输入错误,这可能是一个潜在问题,因为它会以其他方式干扰程序 有没有办法在避免外部输入的同时检查所指向数据的大

使用Codesys v2.3,我试图创建一个功能块,用于检查指针数据的大小,以避免写入超出此范围的部分内存。
例:


如果SIZEOF(pData^)4那么
回来
结束(如有)
数据大小:=SIZEOF(pData^);
现在,如果我将一个字节的地址放入这个块的pData中,if仍然会检查出来,因为解引用指针似乎只返回我们所指向的大小(在本例中为实)

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


有没有办法在避免外部输入的同时检查所指向数据的大小?

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


其他环境的解决方案:


对于TwinCAT 3,可以通过使用
T_Arg
F_INT
等辅助工具创建一个输入解决方案,但我认为Codesys 2没有(有人确认吗?)。在该解决方案中,您必须无论如何更改函数调用,以便指针不会成为输入

在该解决方案中,您可以创建一个输入为
T_Arg
的函数。然后对每个数据类型使用一个helper函数来调用它。从
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
数据类型,可以将任何内容作为参数,并获取其大小。区别在于它不接受
指针
作为输入

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^
);

为什么您需要这样一个函数,只是为了检测可变大小,而这个函数已经存在

您只需直接在程序内部调用
SIZEOF()
。您不需要使用指针。据我所知,您使用它们是因为您希望使输入变量成为任何类型的通用变量,而不是因为您在程序中使用指针。所以原始变量都是直接分配的

您的函数试图创建一个环绕
SIZEOF()
,而不改变计算算法中的任何内容,然后只使用
SIZEOF()
,因为这就是该函数的用途

告诉我为什么要创建单独的函数和 I’我会相应地修改答案

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

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);

首先,它不应该是一个功能块,而是一个函数。其次,我们讨论的是CoDeSys 2.3,它不支持
ANY
ANY_NUM
数据类型。至少我的实例没有。第三,变量不是ST中的对象,您不能对输入变量进行
Test.diSize
,除非它是带有属性
diSize
的结构
Test
。Jabbi要求一个功能块,这就是为什么它是一个。在运行时调试函数块比调试函数更容易。但是是的,这应该是一个函数。我还提到,我认为Codesys 2.3不支持它,在匆忙发表评论之前,您是否阅读了我的回答?第三点:
ANY
被转换成一个结构,因此
Test.diSize
就像一个结构一样工作。兄弟,冷静点,我只是在分享我的经验。我不是在编辑或删除你的答案。说说我的想法。很抱歉,我的评论中有一些批评。但它不是愤怒和仇恨中的批评家。这是建设性的批评。你可以说“谢谢你,Sergey,你的宝贵意见”,而不是进入防守位置。遗憾的是,CoDeSys 2中没有这样的选项,拥有它真的很好。正如Sergey在评论中提到的,“DataSize:=SIZEOF(pData^);”应该被其他代码替换,我意识到这是一个糟糕的例子。我的想法是制作一个函数/块,它可以检测传入数据的大小,并相应地执行操作。它主要被认为是制作一个具有可变数组输入的函数块的一种方法,以便单个函数块可以处理多个情况。我问题中的例子就是,一个例子。这并不是我所理解的全部。我正在更改答案并添加答案。
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);