Adding and deleting UaNodes from NodeManager (C++ Server SDK
Posted: 19 Apr 2012, 08:46
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:
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;
}