jzhvymetal77 - 1 day ago

I had this code working in a previous version of CoDeSys to read variables from a GVL that were added to the Symbol configuration. The problem now is that when I get the _IBaseTreeNode_Parent, it returns a valid interface, but none of the methods or properties work.

If you monitor the _IBaseTreeNode in the watch window, it does show the correct child count. However, it fails at step 30, where the child count incorrectly returns zero. In the image, you can see that the watch window displays the correct value that the property should return.

Attached is the full project code.

FUNCTION_BLOCK Symbols_TO_STR
VAR_INPUT
    i_sPath                     :   STRING(255);
    i_diIndexChild              :   DINT;
    i_diIndexComponent          :   DINT; 
END_VAR
VAR_OUTPUT
    q_diChildCount              :   DINT;
    q_diComponentCount          :   DINT;
    q_sName                     :   STRING(255);
    q_sValue                    :   STRING(255);
    q_sType                     :   STRING(80);
    q_sErrorResult              :   STRING(80);
END_VAR
VAR
    uiStepCopy                  :   UINT;
    uiStep                      :   UINT;
    uiStepProcessCopy           :   UINT;
    uiStepProcess               :   UINT;

    _IBase                      :   IecVarAccessLibrary.IBase;
    _pIIecVarAccess5            :   POINTER TO IecVarAccessLibrary.IIecVarAccess5;
    _IIecVarAccess5             :   IecVarAccessLibrary.IIecVarAccess5;
    _RTS_IEC_RESULT             :   IecVarAccessLibrary.RTS_IEC_RESULT;
    _udiResult                  :   UDINT;
    _VariableInformationStruct  :   IecVarAccessLibrary.VariableInformationStruct;
    _IBaseTreeNode_Parent       :   IecVarAccessLibrary.IBaseTreeNode;

    _IBaseTreeNode_Child        :   IecVarAccessLibrary.IBaseTreeNode;  
    _ITypeDesc_Child            :   IecVarAccessLibrary.ITypeDesc;
    _TypeDescAsUnion_Child      :   IecVarAccessLibrary.TypeDescAsUnion;
    _arIBaseTreeNode_Child      :   ARRAY[0..20] OF IecVarAccessLibrary.IBaseTreeNode;
    _TypeClass_Child            :   IecVarAccessLibrary.IBaseLibrary.TypeClass;
    _psSymbolName_Child         :   POINTER TO STRING;
    _sSymbolName_Child          :   STRING(255);

    _IBaseTreeNode_Component    :   REFERENCE TO IecVarAccessLibrary.IBaseTreeNode; 
    _TypeClass_Component        :   IecVarAccessLibrary.IBaseLibrary.TypeClass;
    _ByteAddress_Component      :   __XWORD;    
    _ByteOffset_Component       :   __XWORD;    
    _sArrayIndexName_Component  :   STRING(20);
    _diArrayIndexCalc_Component :   DINT;
    _diArrayIndexValue_Component:   DINT;
    _psSymbolName_Component     :   POINTER TO STRING;
    _sSymbolName_Component      :   STRING(255);
END_VAR

    uiStepCopy:=uiStep;
    uiStepProcessCopy:=uiStepProcess;
    CASE uiStep OF  
        10: // GET IBASE FROM CURRENT APP
            _IBase:= IecVarAccessLibrary.IecVarAccGetFirstInterface2(0);
            IF _IBase<>0 THEN
                uiStep:=20;
            ELSE    
                q_sErrorResult:=CONCAT(UINT_TO_STRING(uiStep), ': IecVarAccGetFirstInterface2');
                uiStep:=9000;
            END_IF
        20:  //QueryInterface IIecVarAccess5 from IBASE     
            _pIIecVarAccess5 := _IBase.QueryInterface(IecVarAccessLibrary.ITFID_IIecVarAccess5, ADR(_RTS_IEC_RESULT));
            IF _pIIecVarAccess5<>0 AND _RTS_IEC_RESULT=0 THEN
                _IIecVarAccess5 := _pIIecVarAccess5^;
                uiStep:=30;
            ELSE    
                q_sErrorResult:=CONCAT(UINT_TO_STRING(uiStep), ': QueryInterface_IIecVarAccess5');
                uiStep:=9000;
            END_IF
        30:  // Get IBaseTreeNode_Parent
            _IBaseTreeNode_Parent := _IIecVarAccess5.VarAccGetNode3(ADR(i_sPath), ADR(_VariableInformationStruct), ADR(_RTS_IEC_RESULT));
            IF _IBaseTreeNode_Parent<>0 AND _RTS_IEC_RESULT=0 THEN
                q_diChildCount:=_IBaseTreeNode_Parent.ChildCount;

                uiStep:=40;
            ELSE    
                q_sErrorResult:=CONCAT(UINT_TO_STRING(uiStep), ': IBaseTreeNode_Parent');
                uiStep:=9000;
            END_IF
        40:  // Get IBaseTreeNod_Child
            IF(q_diChildCount-1>=i_diIndexChild AND i_diIndexChild >=0) THEN
                _IBaseTreeNode_Child := _IBaseTreeNode_Parent.GetChild(i_diIndexChild);
                IF _IBaseTreeNode_Child<>0 THEN
                    uiStep:=50;
                ELSE    
                    q_sErrorResult:=CONCAT(UINT_TO_STRING(uiStep), ': IBaseTreeNode_Parent');
                    uiStep:=9000;
                END_IF      
            ELSE
                q_sErrorResult:=CONCAT(UINT_TO_STRING(uiStep), ': i_diIndexChild OutBounds');
                uiStep:=9000;
            END_IF