如何确定指针索引成员的类型

发布于 2025-02-03 00:57:11 字数 2593 浏览 1 评论 0 原文

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

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(层次主奴分布)框架的合同部分。例如,状态的批处理初始化。例如:如果要实现类步骤对象的批处理初始化,则只需要将第一步的指针传递给初始化函数,并且该函数将根据第一个指针自动搜索,直到找到一个对象不是步骤类,而是停止搜索。此过程需要自动化。为了实现此类功能,您需要指针的索引,并确定指针索引成员的类型。理想代码:

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); 感觉到当前的指针实施机制,这种功能似乎很难实现。期待启动收集功能。

How to determine the type of a pointer indexed member.
I intend to use:

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;

In addition, Do you have any application cases for CheckPointer?

EDIT:2022-06-05

This is to better implement the contracted part of the HMSD(Hierarchical Master-Slave Distribution) framework. For example, batch initialization of states. For example: if you want to implement batch initialization of objects of class Step, you only need to pass the pointer of the first Step to the initialization function, and the function will automatically search down according to the first pointer until it finds an object that is not of the Step class and stops searching. This process needs to be automated. To achieve such a function, you need the index of the pointer, and determine the type of the pointer index member. Ideal code:

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 );
Feeling the current mechanism of pointer implementation, such a function seems to be difficult to achieve. Looking forward to the launch of the collection function.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

浅浅淡淡 2025-02-10 00:57:11

您无法知道指针指向的数据的类型。创建指针时,您会明确地告诉编译器假设数据是指定类型的。

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

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 的大小相同
  • ,没有其他类型的类型 在我认为,在我看来,在代码序列中依次定义变量之间的变量
  • 也必须按照相同的顺序放置在内存中(不知道这是否为真)

,我认为以上是非常错误的。一种更好的方法可能是“捆绑”专用结构中的元素(在模拟器上测试):

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

You can't know the type of the data the pointer points to. When you create the pointer, you are explicitly telling the compiler to assume the data is of the specified type.

You could store the address of the first and last elements and iterate between them (haven't tested):

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

However, the above assumes that:

  • All of elemX are of the same size
  • There are no other type of variables in between the elements
  • Sequentially defined variables in CODESYS must also be placed in memory sequentially in the same order (don't know if this is true)

As such, the above is very error prone in my opinion. A better approach might be to "bundle" the elements in a dedicated structure (tested on a simulator):

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

Assuming that the bunle structure only contains the desired structs of the same type (and size), this should work as structures should have a continuous memory segment.

I still think that if you want to access normal variables with an index, the best, and least error prone, solutions is to bind them into an array:

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文