Writing a generic function with ANY

Krowi
2019-05-02
2020-04-15
  • Krowi - 2019-05-02

    I've started working with CoDeSys about 2 years ago and I want to try something new. I come from C# language and there what I want to do is easy, in CoDeSys however it isn't. I want to create a generic function like MIN, MAX, LIMIT, ... The goal of the function is to have a single input and limit it between its range. EXT_WORD_LIMIT for examples will limit the input value between min and max that a WORD can have.

    I've done some digging over the past 2 days and I've got a part of the solution. This is what I have:

    FUNCTION EXT_WORD_LIMIT : WORD
    VAR_INPUT
       anyValue   : ANY_BIT;
    END_VAR
    VAR
       lwValue   : LWORD;
    END_VAR
    SysMemCpy(ADR(lwValue),   anyValue.pValue,   TO_LWORD(anyValue.diSize));
    EXT_WORD_LIMIT   := TO_WORD(LIMIT(VALUE_MIN, lwValue, VALUE_MAX));
    

    This way I'm able to put in a BYTE, WORD, DWORD and LWORD and get a WORD back. I would however like something more like the following code. You give a value and a type and you get a limited value back based on the provided type. This piece of code does not throw me any errors but I'm pretty sure it will not work but I'm not sure how to get it to work and IF it will work.

    FUNCTION EXT_LIMIT : ANY_BIT
    VAR_INPUT
       anyValue   : ANY_BIT;
       anyType      : TYPE_CLASS;
    END_VAR
    VAR
       lwValue   : LWORD;
    END_VAR
    SysMemCpy(ADR(lwValue),   anyValue.pValue,   TO_LWORD(anyValue.diSize));
    EXT_LIMIT   := LIMIT("MIN value based on anyType", lwValue, "MAX value based on anyType");
    

    When trying to call the above function I get an error though: "Cannot convert type 'ANY_BIT' to type 'WORD'".

    WORDValue := EXT_LIMIT(DWORDValue, __SYSTEM.TYPE_CLASS.TYPE_WORD);
    

    Has somebody found a solution on how to write generic functions in the way I want it or is this still not possible with CoDeSys? I tried to reverse engineer the MIN,MAX, LIMIT functions but I'm not able to figure out how to do it.

     
  • Krowi - 2019-05-06

    Yes, I've already read that article and it does explain how to read in INPUT variables and I got that to work. How to output an ANY variable without having to do the same in the code calling the function is however not possible in CoDeSys as far as I know. At this moment it looks to me as writing functions in the way MAX, MIN, LIMIT, ... is done is not yet possible for us developers.

     
  • dFx

    dFx - 2019-05-06

    +1 need of an overload system for function accepting different parameters/datatypes

     
  • robertklonek - 2020-04-15

    There is a way around to to that - instead of returning generic variable, writing result value to the given pointer:

    FUNCTION EXT_LIMIT
    VAR_INPUT
       anyValue     : ANY_BIT;
       result       : POINTER TO BYTE;
    END_VAR
    VAR
       lwValue      : LWORD;
    END_VAR
    
    SysMemCpy(ADR(lwValue),   anyValue.pValue,   TO_DWORD(anyValue.diSize));
    lwValue  := LIMIT(0, lwValue, 10);
    SysMemCpy(result,   ADR(lwValue),   TO_DWORD(anyValue.diSize));
    

    The function call is not beautiful, but it works ;-)

    EXT_LIMIT(BYTEValue, ADR(BYTEResult));
    EXT_LIMIT(WORDValue, ADR(WORDResult));
    EXT_LIMIT(DWORDValue, ADR(DWORDResult));
    
     

Log in to post a comment.