首先我们来看一下源码中的这两个数据结构,下面的论述均是基于此。
* An identifier for a node in the address space of an OPC UA Server. */
enum UA_NodeIdType {
UA_NODEIDTYPE_NUMERIC = 0, /* In the binary encoding, this can also
* become 1 or 2 (two-byte and four-byte
* encoding of small numeric nodeids) */
UA_NODEIDTYPE_STRING = 3,
UA_NODEIDTYPE_GUID = 4,
UA_NODEIDTYPE_BYTESTRING = 5
};
typedef struct {
UA_UInt16 namespaceIndex;
enum UA_NodeIdType identifierType;
union {
UA_UInt32 numeric;
UA_String string;
UA_Guid guid;
UA_ByteString byteString;
} identifier;
} UA_NodeId;
UA_NodeId类型中包含了节点所在的名字空间,节点标识类型,以及节点标识类型的值。其中节点标识类型有四种,这里我们暂且只讨论前两种分别是数值和字符串。节点类型通过一个枚举给出,数值类型为0,1,2。0为默认,1指定为2个字节,2指定为4个字节。3为字符串类型。
我们采用字符串标识变量节点,调用接口函数:UA_NodeId varNodeId = UA_NODEID_STRING(2, varName);
在UA_NodeId point_4 = addVariable(server, objectId, UA_TYPES_UINT16);
函数里,函数调用后,以及修改value的值之后分别打印varNodeId.identifier.string.data
的值。
printf("varNode.identifier = %s\n", varNodeId.identifier.string.data);
三次打印结果是一样的,证明是同一个变量节点。
同样,在UaExpert客户端中我们也可以看到变量节点的标识信息。
其中NS2代表名字空间为2;
string代表标识类型为string;
The answer是string的值。
下面我将节点的标识改为数字,首先定义一个id,int id = 99;
然后在初始化这个节点时,用数字标识它:UA_NodeId varNodeId = UA_NODEID_NUMERIC(2, id);
我们在UA expert客户端中再次查看此变量节点:
此节点的标识变成了numeric,标识的值为定义的99。
另外,如何理解一个节点标识和displayName的关系呢?
attr.displayName = UA_LOCALIZEDTEXT("en-US",varName);
我们可以把一个变量节点想象为一个人,节点标识就是他的身份证,其中如果用numeric标识,就是身份证号码,如果用string标识就是人的姓名。而displayName可以理解成人的小名。因此我们只要通过节点的身份标识就一定可以找到此节点。
attr.description = UA_LOCALIZEDTEXT("en-US",displayname);
Description则为对此节点的描述。
BrowseName用以下函数UA_QualifiedName myIntegerName = UA_QUALIFIEDNAME(2, displayname);
定义。