这两段代码:

1
2
3
4
5
6
var serverHandles = new int[2] { 0, item.ServerHandle };
var serverHandleArray = (Array)serverHandles;
var values = new object[2];
var valuesArray = (Array)values;
var errors = new string[2];
var errorsArray = (Array)errors;

1
2
3
4
5
6
7
group.SyncRead((short)OPCAutomation.OPCDataSource.OPCDevice,
1,
ref serverHandleArray,
out valuesArray,
out errorsArray,
out var qualities,
out var timeStamps);

是否需要“记住”它们?

答案是:不需要死记硬背,但要理解其作用和使用方式。

这类代码属于 调用 OPC DA COM 接口时的模板代码(boilerplate code),主要目的是为了和 OPC 服务器进行交互,尤其是进行数据读写操作。


🧠 理解这两段代码的作用

第一段:准备参数

1
2
3
4
5
6
var serverHandles = new int[2] { 0, item.ServerHandle };
var serverHandleArray = (Array)serverHandles;
var values = new object[2];
var valuesArray = (Array)values;
var errors = new string[2];
var errorsArray = (Array)errors;

这段代码是在准备调用 SyncRead() 所需的参数:

  • serverHandles:服务器为每个 OPC 项分配的句柄(Handle),这里传入了两个值,第一个是占位符(0),第二个是要读取的项的句柄。
  • serverHandleArray:将数组转换为 Array 类型,因为 OPC 接口要求使用 COM 兼容的类型。
  • valuesArray:用于接收读取到的数据。
  • errorsArray:用于接收错误信息。

为什么要用 Array 类型?
因为 OPC DA 是基于 COM 的接口,很多方法要求传入 Array 类型,而不是 .NET 的强类型数组。


第二段:调用同步读取方法

1
2
3
4
5
6
7
group.SyncRead((short)OPCAutomation.OPCDataSource.OPCDevice,
1,
ref serverHandleArray,
out valuesArray,
out errorsArray,
out var qualities,
out var timeStamps);

这是调用 SyncRead() 方法,从设备中同步读取数据。

参数 含义
(short)OPCDataSource.OPCDevice 表示直接从设备读取(而不是从缓存)
1 要读取的项数
ref serverHandleArray 要读取的 OPC 项的服务器句柄数组
out valuesArray 输出:读取到的值
out errorsArray 输出:错误信息
out qualities 输出:数据质量(如 OPCQualityGood)
out timeStamps 输出:时间戳

📚 是否需要“记住”?

❌ 不建议死记硬背,因为:

  • 这些代码是 COM 接口调用的模板代码,每次调用都差不多。
  • 它们没有业务逻辑,只是“技术性代码”。
  • 你可以:
    • 把这些代码封装成一个方法(比如 ReadOPCValue())。
    • 或者使用更现代的 OPC UA 客户端库(.NET Standard),它们更友好。

✅ 建议做法

1. 封装成方法

你可以写一个方法来简化调用过程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public object ReadOPCTag(OPCGroup group, OPCItem item)
{
var serverHandles = new int[] { 0, item.ServerHandle };
var serverHandleArray = (Array)serverHandles;
var values = new object[2];
var valuesArray = (Array)values;
var errors = new string[2];
var errorsArray = (Array)errors;

group.SyncRead((short)OPCDataSource.OPCDevice,
1,
ref serverHandleArray,
out valuesArray,
out errorsArray,
out var qualities,
out var timeStamps);

// 返回第一个(实际数据)
return valuesArray.GetValue(1);
}

调用方式:

1
2
var value = ReadOPCTag(group, item);
label1.Text = value.ToString();

2. 使用 OPC UA 替代 OPC DA(推荐)

如果你有选择权,可以考虑使用 OPC UA(Unified Architecture),它基于现代通信协议(TCP/IP、加密、服务化),比 OPC DA 更加稳定、安全、跨平台。例如使用 OPC UA .NET Standard Stack


✅ 总结

问题 回答
这两段代码需要记住吗? ❌ 不需要死记硬背,理解其作用即可。
它们是做什么的? 准备参数并调用 OPC 的同步读取接口。
能不能简化? ✅ 可以封装成方法,提高复用性和可读性。
有没有更好的方式? ✅ 推荐使用 OPC UA 库,避免使用老旧的 OPC DA。