Variant
darra::opcua::Variant 是 OPC UA 通用值容器, 覆盖全部内置数据类型. SDK 用它在 C++ 与 native 之间传值. Move-only, 析构自动释放.
配套
- 包装值 + 时间戳 + 状态请看 DataValue.
- 标准节点常量请看 WellKnownNodes.
公共属性 (访问器)
| 类别 | 属性 | 类型 | 访问 | 说明 |
|---|---|---|---|---|
| 状态 | IsScalar() | bool | R | 是否标量 |
IsArray() | bool | R | 是否数组 | |
| 类型 | DataType() | DarraUa_BuiltinType | R | 内置类型枚举 |
Handle() | DarraUa_Variant* | R | C 层句柄 (内部用) |
构造 (默认 + 借用)
Variant v; // 空 Variant, owns=true
Variant v2(handle, /*owns=*/false); // 借用 native handle, 不拥有
设值 (链式 Setter)
Variant v;
v.SetBool(true); // Boolean
v.SetSByte(-1); // SByte
v.SetByte(255); // Byte
v.SetInt16(42); // Int16
v.SetUInt16(42); // UInt16
v.SetInt32(42); // Int32
v.SetUInt32(42); // UInt32
v.SetInt64(42LL); // Int64
v.SetFloat(3.14f); // Float
v.SetDouble(3.14); // Double
v.SetString("hello"); // String
v.SetDateTime(file_time_utc); // DateTime (FileTime: 100ns since 1601)
链式调用:
Variant v; v.SetDouble(3.14).SetString("override"); // 最后一个生效
取值 (Try* 安全 Getter)
bool b; v.TryGetBool(b);
int8_t i8; v.TryGetSByte(i8);
uint8_t u8; v.TryGetByte(u8);
int16_t i16; v.TryGetInt16(i16);
uint16_t u16; v.TryGetUInt16(u16);
int32_t i32; v.TryGetInt32(i32);
uint32_t u32; v.TryGetUInt32(u32);
int64_t i64; v.TryGetInt64(i64);
double d; v.TryGetDouble(d);
float f; v.TryGetFloat(f);
std::string s = v.AsString(); // 失败返回 ""
int64_t ft = v.AsFileTime(); // FileTime, 失败返回 0
TryGet* 类型不匹配时返回 false, 不抛异常. C++ 风格鼓励用 Try* 而不是抛异常.
内存所有权 (RAII)
Variant 持有 native handle:
- 自己
Variant v;默认构造的 —owns=true, dtor 自动 Delete - 从
s.Read(...).Value()借用的 —owns=false, dtor 不释放 (DataValue 持有) - 从
s.Call(...)返回数组里的 —owns=true, dtor 自动 Delete
最佳实践 — 总是栈对象:
{
Variant v;
v.SetDouble(42.0);
s.Write("ns=2;s=Setpoint", v);
} // 离开作用域: v 自动析构
// 或临时对象
Variant tmp;
tmp.SetInt32(123);
s.Write("ns=2;s=X", tmp);
不要 new Variant(...), 也不要 deep copy (拷贝构造已 delete, 编译报错).
Move 语义
Variant a; a.SetInt32(123);
Variant b = std::move(a); // OK, a 此后失效
// Variant c = a; // 编译错误: copy ctor deleted
可以放进 std::vector<Variant>, 但只能 move 进去:
std::vector<Variant> args;
{ Variant v; v.SetInt32(3); args.push_back(std::move(v)); }
{ Variant v; v.SetInt32(4); args.push_back(std::move(v)); }
auto outs = s.Call("ns=2;s=Calc", "ns=2;s=Calc.Add", args);
BuiltinType 枚举
Null, Boolean, SByte, Byte, Int16, UInt16, Int32, UInt32, Int64, UInt64,
Float, Double, String, DateTime, Guid, ByteString, XmlElement,
NodeId, ExpandedNodeId, StatusCode, QualifiedName, LocalizedText,
ExtensionObject, DataValue, Variant, DiagnosticInfo
数字 0..25, 详见 darra_opcua/darra_opcua.h 中的 DarraUa_BuiltinType.
ExtensionObject (复杂结构)
OPC UA Server 自定义 Struct DataType 通过 ExtensionObject 包装. 当前 SDK 提供基础 ExtensionObject 容器, 完整 schema 解析在后续版本.