跳到主要内容

结构体解码

概述

OPC UA 1.04+ 把每个自定义结构体的字段定义放到 DataType 节点的 DataTypeDefinition 属性 (AttributeId=27, Part 5 §6.4.2)。StructDecoder 实现完整协议层。

API

成员类别读写说明
StructDecoder::new(ua)构造绑定到会话
decoder.decode(variant)方法返回 Result<DynamicExtensionObject>
decoder.decode_body(bytes, data_type_id)方法直接给字节
decoder.get_definition(data_type_id)方法获取 / 缓存
decoder.prefetch_definitions(ids)方法预热
obj.get(field_name)方法取字段 (返回 Option<&FieldValue>)
obj.fields()方法字段名→值 HashMap
obj.definition()方法StructDefinition

相关结构:

pub enum StructureKind {
Structure = 0, // 普通
StructureWithSubtypedValues = 1, // 含子类型
StructureWithOptionalFields = 2, // 含可选 (前置 EncodingMask)
Union = 3, // Union (前置 selector)
UnionWithSubtypedValues = 4, // Union + 子类型
}

pub enum FieldValue {
Bool(bool),
Int64(i64),
UInt64(u64),
Float(f32),
Double(f64),
String(String),
Bytes(Vec<u8>),
DateTime(DateTime<Utc>),
Nested(Box<DynamicExtensionObject>),
Array(Vec<FieldValue>),
Null,
}

代码示例

use opcua::{DarraOpcUa, StructDecoder, FieldValue};

let ua = DarraOpcUa::new("opc.tcp://localhost:4840")?;
ua.connect()?;

let dec = StructDecoder::new(&ua);

// 1) 读自定义结构
let dv = ua.read("ns=2;s=Robot.CurrentPose", AttributeId::Value)?;
let pose = dec.decode(&dv.value)?;

if let Some(FieldValue::Double(x)) = pose.get("X") { println!("x = {}", x); }
if let Some(FieldValue::Double(y)) = pose.get("Y") { println!("y = {}", y); }

// 2) 全字段遍历
for (name, value) in pose.fields() {
println!("{} = {:?}", name, value);
}

// 3) 嵌套
if let Some(FieldValue::Nested(quat)) = pose.get("Quaternion") {
if let Some(FieldValue::Double(qw)) = quat.get("W") {
println!("qw = {}", qw);
}
}

// 4) 数组字段
if let Some(FieldValue::Array(arr)) = pose.get("JointAngles") {
for a in arr {
println!("{:?}", a);
}
}

// 5) 预热
dec.prefetch_definitions(&["ns=2;i=3001", "ns=2;i=3002"])?;

实现限制

  • Native 层未导出 ExtensionObject 字节提取接口, decode(variant) 在拿不到字节时返回 FieldValue::Null 占位
  • 协议层全部已实现, native 接通后 decode_body(bytes, type_id) 立刻可用
  • DiagnosticInfo 跳过

最佳实践

  • 共享一个 decoder, 字段表缓存复用
  • prefetch_definitions 启动时调
  • 嵌套结构 match 解构访问
  • Union 看 definition().is_union()

跨语言对照

C#PythonJavaC++RustC
StructDecoderStructDecoderStructDecoderStructDecoderStructDecoderDarraUa_StructDecoder
DecodedecodedecodeDecodedecodeDarraUa_StructDecoder_Decode

下一步