Page 1 of 1

Adding and deleting UaNodes from NodeManager (C++ Server SDK

Posted: 19 Apr 2012, 08:46
by Support Team
This is a short tutorial for adding and deleting nodes from a NodeManager derived from NodeManagerUaNode e.g. NodeManagerBase.

All classes derived from UaNode are reference counted. They should never be deleted directly. If you own a reference, you must use pNode->releaseReference() to release this reference. Most classes derived from UaNode should have a protected destructor and it is not possible for them to use delete directly.

As soon as you added the node to the NodeManager (addNodeAndReference or addUaNode), the NodeManager is responsible for the one reference added during creation of the node. The NodeManager will automatically release all of the nodes when shutting down.

If adding a node fails e.g. a node with the NodeId already exists, you must release the reference (pNode->releaseReference()) to clear the node and to free the memory.

If you want to delete a node and all children from a NodeManager, the only method you need is deleteUaNode(pNodeToDelete, OpcUa_True, OpcUa_True, OpcUa_True) with all flags set to True. This releases the NodeManager references to the node and the child nodes and removes all UaReferences between the nodes and also the reference to the parent node.

If you got the node pointer through NodeManagerUaNode::getNode(const UaNodeId& nodeId) you must also release the reference to the node (pNode->releaseReference()) that was added through getNode().

Here is some sample code:

Code: Select all

    UaStatus addResult;
    // Namespace index of the Nodemanager
    OpcUa_UInt16 nsIdx = getNameSpaceIndex();
    // NodeIds for the nodes to create
    UaNodeId myFolderId("MyFolder", nsIdx);
    UaNodeId myVariable("MyFolder.MyVariable", nsIdx);

    // Create a folder with one child (variable)
    OpcUa::FolderType* pFolder = new OpcUa::FolderType(myFolderId, "MyFolder", nsIdx, this);
    addResult = addNodeAndReference(OpcUaId_ObjectsFolder, pFolder, OpcUaId_Organizes);
    if ( addResult.isNotGood() )
    {   // Release reference if adding node to NodeManager failed
        pFolder->releaseReference();
    }
    else
    {
        UaVariant initialValue;
        initialValue.setUInt32(0); // Assing data type UInt32 and set intial value to 0
        OpcUa::BaseDataVariableType* pVariable = new OpcUa::BaseDataVariableType(
            myVariable, "MyVariable", nsIdx, initialValue, OpcUa_AccessLevels_CurrentReadOrWrite, this);
        addResult = addNodeAndReference(pFolder, pVariable, OpcUaId_HasComponent);
        if ( addResult.isNotGood() )
        {   // Release reference if adding node to NodeManager failed
            pVariable->releaseReference();
        }
    }


    // Later on you want to delete the folder


    // Option 1 - you have the node pointer already
    // Delete the node and all children
    deleteUaNode(pFolder, OpcUa_True, OpcUa_True, OpcUa_True);


    // Option 2a - you know only the NodeId (Inside the NodeManager)
    UaNodeId myFolderId("MyFolder", nsIdx);
    UaNode* pNode = getNode(myFolderId);
    if ( pNode )
    {
        // Delete the node and all children
        deleteUaNode(pNode, OpcUa_True, OpcUa_True, OpcUa_True);
        // Release the reference adde by getNode()
        pNode->releaseReference();
        pNode = NULL;
    }

    // Option 2b - you know only the NodeId (Outside the NodeManager)
    UaNodeId myFolderId("MyFolder", pNodeManager->getNameSpaceIndex());
    UaNode* pNode = pNodeManager->getNode(myFolderId);
    if ( pNode )
    {
        // Delete the node and all children
        pNodeManager->deleteUaNode(pNode, OpcUa_True, OpcUa_True, OpcUa_True);
        // Release the reference adde by getNode()
        pNode->releaseReference();
        pNode = NULL;
    }