跳到主要内容

OpcUaNodeId — 强类型 NodeId

概述

OPC UA 节点 ID 默认用字符串编码 ("ns=2;s=Foo")。OpcUaNodeId 是不可变值类型, 显式带 namespace / id_type / identifier 三件套。

对应规范段: Part 6 §5.2.2。

API

成员类别读写说明
OpcUaNodeId::Null静态空哨兵
OpcUaNodeId::FromNumeric(ns, id)工厂数字型
OpcUaNodeId::FromString(ns, id)工厂字符串型
OpcUaNodeId::FromGuid(ns, uuid)工厂GUID 型
OpcUaNodeId::FromOpaque(ns, bytes)工厂不透明型
OpcUaNodeId::Parse(s)静态解析, 失败抛 std::invalid_argument
OpcUaNodeId::TryParse(s, out_nid)静态安全解析, 返回 bool
nid.ToString()序列化
nid.namespace_index() / id_type() / identifier() / IsNull()属性字段

相关结构:

  • Numeric (0) — 编码 i=, uint32
  • String (1) — 编码 s=, UTF-8
  • Guid (2) — 编码 g=, {xxxx-...}
  • Opaque (3) — 编码 b=, base64

代码示例

#include <darra/opcua.h>
using namespace darra::opcua;

// 1) 工厂
auto n1 = OpcUaNodeId::FromNumeric(0, 84); // i=84
auto n2 = OpcUaNodeId::FromString(2, "Boiler1.Temp");
auto n3 = OpcUaNodeId::FromGuid(3, /*uuid_t*/ ...);
auto n4 = OpcUaNodeId::FromOpaque(4, std::vector<uint8_t>{1,2,3});

// 2) 解析
auto n5 = OpcUaNodeId::Parse("ns=2;s=Demo.Tag");
std::cout << "ns=" << n5.namespace_index() << ", type=" << n5.id_type() << "\n";

OpcUaNodeId n6;
if (!OpcUaNodeId::TryParse("ns=99;i=foo", n6))
std::cout << "invalid\n";

// 3) 序列化
auto s = n2.ToString(); // "ns=2;s=Boiler1.Temp"

// 4) 与 SDK 互转
auto dv = ua.Read(n2.ToString());

// 5) 字典 key (有 operator< / std::hash 特化)
std::map<OpcUaNodeId, std::string> dict;
dict[n2] = "锅炉一温度";

// 6) Null
std::cout << OpcUaNodeId::Null.IsNull() << "\n"; // 1

最佳实践

  • 配置文件存字符串, 加载用 Parse
  • 代码内部用强类型
  • Numeric 优先 (uint 比较快)
  • 用户输入永远先 TryParse

跨语言对照

C#PythonJavaC++RustC
OpcUaNodeIdOpcUaNodeIdOpcUaNodeIdOpcUaNodeIdOpcUaNodeIdDarraUa_NodeId
ParseparseparseParseparseDarraUa_NodeId_Parse
FromNumericfrom_numericfromNumericFromNumericfrom_numericDarraUa_NodeId_FromNumeric

下一步