【问题标题】:How to determine the type of a pointer indexed member如何确定指针索引成员的类型
【发布时间】:2022-06-14 21:38:48
【问题描述】:

如何确定指针索引成员的类型。 我打算用:

TYPE DUT_DemoStruct :
STRUCT
        Member_1: BOOL;
        Member_2: INT;
END_STRUCT
END_TYPE


PROGRAM Prg_Main
VAR
        DemoStructPointer:
        Obj_DemoStruct1: DUT_DemoStruct ;
        Obj_DemoStruct2: DUT_DemoStruct ;
        Obj_DemoStruct3: DUT_DemoStruct ;
        Demo_INT: INT;
        Index: INT;
        _pointer: POINTER TO DUT_DemoStruct;
END_VAR


FOR Index:=0 TO 5 DO
        IF _pointer[Index] THEN  //whether the _pointer[Index] (pointer index member) is of type DUT_DemoStruct
            _pointer[Index].Member_1:=TRUE;
        END_IF;
END_FOR;

另外,你们有CheckPointer的申请案例吗?

编辑:2022-06-05

这是为了更好的实现HMSD(Hierarchical Master-Slave Distribution)框架的约定部分。例如,状态的批量初始化。例如:如果要实现类Step对象的批量初始化,只需将第一个Step的指针传递给初始化函数,该函数会自动根据第一个指针向下搜索,直到找到一个对象不属于 Step 类并停止搜索。这个过程需要自动化。要实现这样的功能,需要指针的索引,并确定指针索引成员的类型。理想代码:

FUNCTION_BLOCK Exe_PalletShuttle EXTENDS Frame.Base_LocalScope
VAR
    {attribute 'hide'}pointer_Step: POINTER TO Frame.Base_Step;
    {attribute 'hide'}step_Start: Frame.Base_Step;

    {attribute 'hide'}step_StartRecharg: Frame.Base_Step;

    {attribute 'hide'}step_LengthwaysMove_Start: Frame.Base_Step;
    {attribute 'hide'}step_LiftShuttleCyd_PutDown: Frame.Base_Step;
    {attribute 'hide'}step_LengthwaysMove_GoTarget: Frame.Base_Step;
    {attribute 'hide'}step_LengthwaysMove_End: Frame.Base_Step;

   {attribute 'hide'}step_WidthwaysMove_Start: Frame.Base_Step;
    {attribute 'hide'}step_LiftShuttleCyd_Uplift: Frame.Base_Step;
    {attribute 'hide'}step_WidthwaysMove_GoTarget: Frame.Base_Step;
    {attribute 'hide'}step_WidthwaysMove_End: Frame.Base_Step;

    {attribute 'hide'}step_UpliftPallet_Start: Frame.Base_Step;
    {attribute 'hide'}step_LiftPalletCyd_Uplift: Frame.Base_Step;
    {attribute 'hide'}step_UpliftPallet_End: Frame.Base_Step;   

    {attribute 'hide'}step_PutdownPallet_Start: Frame.Base_Step;
    {attribute 'hide'}step_LiftPalletCyd_Putdown: Frame.Base_Step;
    {attribute 'hide'}step_PutdownPallet_End: Frame.Base_Step;  

   {attribute 'hide'}step_End: Frame.Base_Step;

   {attribute 'hide'}VividerMark: BOOL;

   {attribute 'hide'}obj_PalletLiftCyd: Frame.Device_Actuator;
    {attribute 'hide'}obj_DiverterLiftCyd: Frame.Device_Actuator;
END_VAR

pointer_Step:= ADR(step_Start); InitialStepScope(FirstAdr:=pointer_Step); 感觉目前指针实现的机制,这样的功能似乎很难实现。期待收藏功能上线。

【问题讨论】:

    标签: codesys


    【解决方案1】:

    你无法知道指针指向的数据类型。创建指针时,您明确告诉编译器假定数据属于指定类型。

    您可以存储第一个和最后一个元素的地址并在它们之间进行迭代(尚未测试):

    elem1: MY_STRUC;
    elem2: MY_STRUC;
    ...
    elemN: MY_STRUC;
    
    pbegin: POINTER TO MY_STRUCT := ADR(elem1);
    pend: POINTER TO MY_STRUCT := ADR(elemN);
    
    WHILE pbegin <> pend DO
        // use pbegin^
        pbegin := pbegin + SIZEOF(pbegin^); // or pbegin := ADR(pbegin[1]);
    END_FOR
    

    但是,以上假设:

    • 所有elemX 大小相同
    • 元素之间没有其他类型的变量
    • CODESYS中顺序定义的变量也必须按相同的顺序依次放入内存中(不知道是不是这样)

    因此,在我看来,上述内容很容易出错。更好的方法可能是将元素“捆绑”在一个专用结构中(在模拟器上测试):

    TYPE MY_STRUC_BUNDLE:
    STRUCT
        elem1: MY_STRUC;
        elem2: MY_STRUC;
        ...
        elemN: MY_STRUC;
    END_STRUCT
    END_TYPE
    
    bundle: MY_STRUC_BUNDLE;
    ptr: POINTER TO MY_STRUCT := ADR(bundle);
    len: UDINT := SIZEOF(bundle) / SIZEOF(ptr^) - 1;
    index: UDINT;
    
    FOR index := 0 TO len DO
        // use ptr[Index]
    END_FOR
    

    假设bunle结构包含相同类型(和大小)的所需结构,这应该可以工作,因为结构应该有一个连续的内存段。

    我仍然认为,如果你想通过索引访问普通变量,最好的也是最不容易出错的解决方案是将它们绑定到一个数组中:

    elem1: MY_STRUC;
    elem2: MY_STRUC;
    ...
    elemN: MY_STRUC;
    
    arr: ARRAY [1..N] OF POINTER TO MY_STRUC := [ADR(elem1), ADR(elem2), ..., ADR(elemN)];
    
    FOR Index := 1 TO N DO
        // use arr[Index]^
    END_FOR
    

    【讨论】:

    • 请参考本题的补充。
    猜你喜欢
    • 2011-04-21
    • 2018-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-21
    • 1970-01-01
    • 2017-03-09
    相关资源
    最近更新 更多