跳到主要内容

Variant

darra::opcua::Variant 是 OPC UA 通用值容器, 覆盖全部内置数据类型. SDK 用它在 C++ 与 native 之间传值. Move-only, 析构自动释放.

配套

公共属性 (访问器)​

类别属性类型访问说明
状态IsScalar()boolR是否标量
IsArray()boolR是否数组
类型DataType()DarraUa_BuiltinTypeR内置类型枚举
Handle()DarraUa_Variant*RC 层句柄 (内部用)

构造 (默认 + 借用)​

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, 详见 opcua/opcua.h 中的 DarraUa_BuiltinType.

ExtensionObject (复杂结构)​

OPC UA Server 自定义 Struct DataType 通过 ExtensionObject 包装. 当前 SDK 提供基础 ExtensionObject 容器, 完整 schema 解析在后续版本.

下一步​