如何利用UA-ModelCompiler实现自定义OPC-UA数据类型的编解码?
OPC UA自定义数据类型编解码(基于UA-.NETStandard)
利用UA-ModelCompiler生成的编解码能力
UA-ModelCompiler生成的自定义数据类型类已经实现了IEncodeable接口,自带Encode()和Decode()方法,完全不需要手动处理字节数组的序列化逻辑。生成的代码里会包含类型的NodeId定义、字段/属性映射,以及完整的编解码逻辑。
封装自定义数据为ExtensionObject
你不需要手动把对象转成字节数组再封装,UA-.NETStandard框架会自动处理这个过程。以下是两种常见场景的实现:
1. 直接封装(推荐)
实例化自定义对象后,直接传入ExtensionObject的构造函数,框架会自动完成编码:
// 实例化你的自定义数据类型对象 var myComplexObj = new MyCustomType { StringProperty = "Test Value", IntProperty = 456, NestedObj = new MyNestedType { BoolProperty = true } }; // 自动封装为ExtensionObject var extensionObj = new ExtensionObject(myComplexObj);
2. 手动编码(按需使用)
如果需要手动控制编码过程(比如指定编码器参数),可以直接调用自定义对象的Encode()方法:
var encoder = new BinaryEncoder(); myComplexObj.Encode(encoder); byte[] encodedBytes = encoder.CloseAndReturnBuffer(); // 手动创建ExtensionObject并赋值 var extensionObj = new ExtensionObject { TypeId = myComplexObj.TypeId, Body = encodedBytes };
服务器端返回自定义数据
在服务器端设置变量值时,直接将自定义对象赋值给变量的Value属性,框架会自动将其封装为ExtensionObject返回给客户端:
// 找到目标变量节点 var targetVariable = (BaseDataVariableState)FindNode(new NodeId("MyCustomVariable", NamespaceIndex)); // 直接赋值自定义对象 targetVariable.Value = new DataValue(myComplexObj); targetVariable.ClearChangeMasks(SystemContext, true);
客户端解析自定义数据
客户端读取到ExtensionObject后,直接将Body转换为生成的自定义类型即可:
// 读取变量值 var readResult = client.ReadValue(new ReadValueId { NodeId = new NodeId("MyCustomVariable", NamespaceIndex) }); // 解析ExtensionObject if (readResult.Value is ExtensionObject extObj) { var customData = (MyCustomType)extObj.Body; // 使用customData的属性 Console.WriteLine($"StringProperty: {customData.StringProperty}"); }
关键注意事项
- 类型一致性:服务器和客户端必须引用UA-ModelCompiler生成的同一版本的C#模型代码,确保自定义类型的NodeId、字段定义完全一致。
- 类型注册:在服务器的
NodeManager中,要确保调用生成代码中的类型注册方法(通常是RegisterCustomTypes()),将自定义类型注册到地址空间。 - 嵌套类型支持:如果自定义类型包含其他自定义类型(嵌套对象),生成的代码会自动处理嵌套编解码,无需额外编写逻辑。
内容的提问来源于stack exchange,提问作者Elijah Pass
相关产品推荐
相关产品推荐

