NumericRange
概述
OPC UA Part 4 §7.27 NumericRange 表示 Value 属性的数组 / 矩阵子范围:
| 字符串 | 含义 |
|---|---|
| "" | 整段 |
| "5" | 第 5 个 |
| "3:7" | 第 3-7 个 |
| "1:3,2:4" | 二维 |
API
| 函数 | 类别 | 读写 | 说明 |
|---|---|---|---|
| DarraUa_NumericRange_All(&out_r) | 工厂 | — | 整段 |
| DarraUa_NumericRange_Single(idx, &out_r) | 工厂 | — | 单一索引 |
| DarraUa_NumericRange_Span(start, end, &out_r) | 工厂 | — | 区间 |
| DarraUa_NumericRange_Multi(dims, n, &out_r) | 工厂 | — | 多维 |
| DarraUa_NumericRange_Parse(s, &out_r) | 静态 | — | 解析 |
| DarraUa_NumericRange_ToString(r, &out_str) | — | — | 序列化, Free |
| DarraUa_NumericRange_Free(r) | 释放 | — | 释放 |
| DarraUa_Session_ReadRange(ua, nid, range, attr, &out_dv) | 扩展 | 读 | 读子段 |
| DarraUa_Session_WriteRange(ua, nid, range, value, &out_status) | 扩展 | 写 | 写子段 |
代码示例
#include <opcua.h>
int main() {
DarraUa_Session* ua;
DarraUa_Session_New("opc.tcp://localhost:4840", &ua);
DarraUa_Session_Connect(ua);
// 1) 单个元素
DarraUa_NumericRange r1;
DarraUa_NumericRange_Single(3, &r1);
DarraUa_DataValue* dv1 = NULL;
DarraUa_Session_ReadRange(ua, "ns=2;s=Arr", &r1, ATTR_VALUE, &dv1);
/* dv1->value 是单个元素 */
DarraUa_FreeDataValue(dv1);
DarraUa_NumericRange_Free(&r1);
// 2) 区间
DarraUa_NumericRange r2;
DarraUa_NumericRange_Span(0, 99, &r2);
DarraUa_DataValue* dv2 = NULL;
DarraUa_Session_ReadRange(ua, "ns=2;s=Arr", &r2, ATTR_VALUE, &dv2);
/* dv2->value 是 100 个元素的数组 */
DarraUa_FreeDataValue(dv2);
DarraUa_NumericRange_Free(&r2);
// 3) 二维子段
DarraUa_NumericRange dim_a, dim_b;
DarraUa_NumericRange_Span(0, 9, &dim_a);
DarraUa_NumericRange_Span(0, 9, &dim_b);
DarraUa_NumericRange dims[] = { dim_a, dim_b };
DarraUa_NumericRange r2d;
DarraUa_NumericRange_Multi(dims, 2, &r2d);
DarraUa_DataValue* dv3 = NULL;
DarraUa_Session_ReadRange(ua, "ns=2;s=Matrix", &r2d, ATTR_VALUE, &dv3);
DarraUa_FreeDataValue(dv3);
DarraUa_NumericRange_Free(&r2d);
// 4) 写单个
DarraUa_NumericRange r4;
DarraUa_NumericRange_Single(0, &r4);
DarraUa_Variant v;
DarraUa_Variant_SetDouble(&v, 42.5);
DarraUa_StatusCode st;
DarraUa_Session_WriteRange(ua, "ns=2;s=Arr", &r4, &v, &st);
DarraUa_NumericRange_Free(&r4);
DarraUa_Session_Free(ua);
return 0;
}
实现说明
- Stack 不提供 *WithRange PInvoke 时 ReadRange/WriteRange 返回
BadNotImplemented - IsAll 时直接转发 Read
错误处理
| StatusCode | 含义 |
|---|---|
| Good | 成功 |
| BadIndexRangeInvalid | range 字符串非法 / 节点非数组 |
| BadIndexRangeNoData | range 在数据范围外 |
| BadTypeMismatch | 写入类型不符 |
最佳实践
- 大数组只取片
- 矩阵按行 / 列拆
- 写入只动改了的索引
- 不要每次都 Parse, 用 Span / Single 工厂
- 释放 NumericRange 内部分配的子 range 数组
跨语言对照
| C# | Python | Java | C++ | Rust | C |
|---|---|---|---|---|---|
| NumericRange | NumericRange | NumericRange | NumericRange | NumericRange | DarraUa_NumericRange |
| ReadRange | read_range | readRange | ReadRange | read_range | DarraUa_Session_ReadRange |
| WriteRange | write_range | writeRange | WriteRange | write_range | DarraUa_Session_WriteRange |