chenluhua1980
2026-01-26 d7c88780e1df54f34563d60bd7fa01011d2eef03
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
#ifndef PERFORMANCE_MELSEC_H
#define PERFORMANCE_MELSEC_H
 
#include "Mdfunc.h"
 
#include <map>
#include <array>
#include <mutex>
#include <string>
#include <vector>
#include <atomic>
#include <sstream>
#include <unordered_map>
 
// 连接参数
#define PLC_MAX_RETRY 3        // 最大重试次数:在与PLC通信时,如果发生通信错误,将最多重试3次
#define PLC_TIMEOUT 500        // 超时时间(毫秒):每次通信操作的超时等待时间为500毫秒
 
/*
 * 网络通道:指定通信所使用的网络通道号,通常在多通道通信中设置
 * 51 到 54 是 MELSECNET/H 的 1-4 通道
 * 81 到 84 是 CC-Link 的 1-4 通道
 * 151 到 154 是 CC-Link IE 控制器网络的 1-4 通道
 * 181 到 184 是 CC-Link IE 现场网络的 1-4 通道
 * 281 到 284 是 CC-Link IE TSN 网络的 1-4 通道
 **/
#define MELSECNET_CHANNEL(x) (50 + (x))           // x 范围:1~4
#define CC_LINK_CHANNEL(x) (80 + (x))              // x 范围:1~4
#define CC_LINK_IE_CONTROL_CHANNEL(x) (150 + (x)) // x 范围:1~4
#define CC_LINK_IE_FIELD_CHANNEL(x) (180 + (x))   // x 范围:1~4
#define CC_LINK_IE_TSN_CHANNEL(x) (280 + (x))     // x 范围:1~4
 
 // 自定义错误码
#define ERROR_CODE_UNKNOWN                0x00010000 // 未知
#define ERROR_CODE_NOT_CONNECTED        0x00020000 // 未连接
#define ERROR_CODE_INVALID_PARAM        0x00030000 // 参数无效
#define ERROR_CODE_INVALID_DATA            0x00040000 // 数据无效
#define ERROR_CODE_STATION_OUT_OF_RANGE 0x00050000 // 站号超出范围
#define ERROR_CODE_GROUP_OUT_OF_RANGE   0x00060000 // 组号超出范围
#define ERROR_CODE_NETWORK_OUT_OF_RANGE 0x00070000 // 网络号超出范围
 
// 板块类型
enum class BoardType {
    UNKNOWN = -1,                                        // 未知类型
    MELSECNET_H = MELSECNET_CHANNEL(1),                    // MELSECNET/H
    CC_LINK_VER_2 = CC_LINK_CHANNEL(1),                    // CC-Link Ver. 2
    CC_LINK_IE_CONTROL = CC_LINK_IE_CONTROL_CHANNEL(1),    // CC-Link IE 控制网络
    CC_LINK_IE_FIELD = CC_LINK_IE_FIELD_CHANNEL(1),     // CC-Link IE 现场网络
    CC_LINK_IE_TSN = CC_LINK_IE_TSN_CHANNEL(1)          // CC-Link IE TSN
};
 
// 软元件类型枚举
enum class DeviceType {
    /*
     * ER、LX、LY、LB、LW、LSB、LSW和SPG软元件都是范围型
     * ER:DevER0~256
     * LX:DevLX1~255,DevLX(x)    (DevX*1000+(x))
     * LY:DevLY1~255,DevLY(x)    (DevY*1000+(x))
     * LB:DevLB1~255,DevLB(x)    (DevB*1000+(x))
     * LW:DevLW1~255,DevLW(x)    (DevW*1000+(x))
     * LSB:DevLSB1~255,DevLSB(x) (DevQSB*1000+(x))
     * LSW:DevLSW1~255,DevLSW(x) (DevQSW*1000+(x))
     * SPG:DevSPG0~255,DevSPG(x) (29*1000+(x))
     * 扩展文件寄存器代码指定(10进制数)的后3位数及软元件名指定的数值中,应指定块No.(0~256)
     * 链接直接软元件代码指定(10进制数)的后3位数及软元件名指定的数值中,应指定网络No.(1~255)
     * 智能功能模块软元件代码指定(10进制数)的后3位数及软元件名指定的数值中,应指定(起始I/ONo.÷16)的值
     * 扩展文件寄存器和链接直接软元件在随机读取(mdRandR、mdRandREx)函数中,即使指定实际不存在的软元件也有可能正常结束
     * MAIL和MAILMC在SEND功能及RECV功能中,与软元件访问一样,指定各功能对应的软元件类型,进行数据的发送(mdSend、mdSendEx)或数据的读取(mdReceive、mdReceiveEx)
     **/
 
    X = 0x0001,      // 输入 (位)
    Y = 0x0002,      // 输出 (位)
    L = 0x0003,      // 锁存继电器 (位)
    M = 0x0004,      // 内部继电器 (位)
    SM = 0x0005,     // 特殊继电器 (位)
    F = 0x0006,      // 报警器 (位)
    TT = 0x0007,     // 定时器 (触点) (位)
    TC = 0x0008,     // 计数器 (线圈) (位)
    CT = 0x0009,     // 计数器 (触点) (位)
    CC = 0x000A,     // 计数器 (线圈) (字)
    TN = 0x000B,     // 定时器 (当前值) (字)
    CN = 0x000C,     // 计数器 (当前值) (字)
    D = 0x000D,      // 数据寄存器 (字)
    SD = 0x000E,     // 特殊寄存器 (字)
    TM = 0x000F,     // 定时器 (设置值主) (字)
    TS = 0x0010,     // 定时器 (设置值主1) (字)
    TS2 = 0x3E82,    // 定时器 (设置值主2) (字)
    TS3 = 0x3E83,    // 定时器 (设置值主3) (字)
    CM = 0x0011,     // 计数器 (设置值主) (字)
    CS = 0x0012,     // 计数器 (设置值主1) (字)
    CS2 = 0x4652,    // 计数器 (设置值主2) (字)
    CS3 = 0x4653,    // 计数器 (设置值主3) (字)
    A = 0x0013,      // 累加器 (字)
    Z = 0x0014,      // 变址寄存器 (字)
    V = 0x0015,      // 变址寄存器 (字)
    R = 0x0016,      // 文件寄存器 (块切换方式) (字)
    ER = 0x55F0,     // 扩展文件寄存器 (块切换方式) (0x55F0~0x56F0) (字) (在随机读取(mdRandR、mdRandREx)函数中,即使指定实际不存在的软元件也有可能正常结束。(读取数据不正确。))
    ZR = 0x00DC,     // 文件寄存器 (连号访问方式) (字)
    B = 0x0017,      // 链接继电器 (位)
    W = 0x0018,      // 链接寄存器 (字)
    QSB = 0x0019,    // 链接特殊继电器 (位)
    STT = 0x001A,    // 累计定时器 (触点) (位)
    STC = 0x001B,    // 累计定时器 (线圈) (位)
    QSW = 0x001C,    // 链接特殊寄存器 (字)
    QV = 0x001E,     // 变址继电器 (位)
    MRB = 0x0021,     // 随机访问缓冲 (字)
    STN = 0x0023,    // 累计定时器 (当前值) (字)
    LZ = 0x0026,     // 超长变址寄存器 (双字)
    RD = 0x0027,     // 刷新数据寄存器 (字)
    LTT = 0x0029,    // 超长定时器 (触点) (位)
    LTC = 0x002A,    // 超长定时器 (线圈) (位)
    LTN = 0x002B,    // 超长定时器 (当前值) (双字)
    LCT = 0x002C,    // 超长计数器 (触点) (位)
    LCC = 0x002D,    // 超长计数器 (线圈) (位)
    LCN = 0x002E,    // 超长计数器 (当前值) (双字)
    LSTT = 0x002F,   // 超长累计定时器 (触点) (位)
    LSTC = 0x0030,   // 超长累计定时器 (线圈) (位)
    LSTN = 0x0031,   // 超长累计定时器 (当前值) (双字)
    SPB = 0x0032,     // 缓冲存储器 (字)
    MAIL = 0x0065,   // 特殊软元件类型:邮件类型 (10进制 101)
    MAILMC = 0x0066, // 特殊软元件类型:无确认邮件 (10进制 102)
    LX = 0x03E8,     // 链接直接软元件 (链接输入) (0x03E9~0x04E7) (位)
    LY = 0x07D0,     // 链接直接软元件 (链接输出) (0x07D1~0x08CF) (位)
    LB = 0x59D8,     // 链接直接软元件 (链接继电器) (0x59D9~0x5AD7) (位)
    LW = 0x5DC0,     // 链接直接软元件 (链接寄存器) (0x5DC1~0x5EBF) (字)
    LSB = 0x61A8,    // 链接直接软元件 (链接特殊继电器) (0x61A9~0x62A7) (位)
    LSW = 0x6D60,    // 链接直接软元件 (链接特殊寄存器) (0x6D61~0x6E5F) (字)
    SPG = 0x7147,    // 智能功能模块软元件 (0x7148~0x7247) (字)
};
 
// 数据类型
enum class DataType {
    BIT = 1,   // 位 (1位)
    WORD = 2,  // 字 (16位)
    DWORD = 4  // 双字 (32位)
};
 
// 控制代码
enum class ControlCode {
    RUN = 0,   // 远程 RUN
    STOP = 1,  // 远程 STOP
    PAUSE = 2  // 远程 PAUSE
};
 
// 版本信息
struct BoardVersion {
    char fixedValue[2];       // 固定值
    char checksum[2];         // 校验和
    char swVersion[2];        // 软件版本
    char date[6];             // 日期 (格式 YYMMDD)
    uint32_t reserved;        // 保留区域 (4 字节)
    char swModel[16];         // 软件型号
    char hwModel[16];         // 硬件型号
    char twoPortMemory[2];    // 两端口存储器占用容量
    char twoPortAttribute[2]; // 两端口属性
    char availableBias[2];    // 可使用偏置
    char moduleType[10];      // 机型类型
 
    // 输出结构体内容为字符串 (便于调试)
    std::string toString() const {
        std::ostringstream oss;
        oss << "Fixed Value: " << fixedValue[0] << fixedValue[1] << "\n"
            << "Checksum: " << checksum[0] << checksum[1] << "\n"
            << "SW Version: " << swVersion[0] << swVersion[1] << "\n"
            << "Date: " << std::string(date, 6) << "\n"
            << "Reserved: " << reserved << "\n"
            << "SW Model: " << std::string(swModel, 16) << "\n"
            << "HW Model: " << std::string(hwModel, 16) << "\n"
            << "Two Port Memory: " << twoPortMemory[0] << twoPortMemory[1] << "\n"
            << "Two Port Attribute: " << twoPortAttribute[0] << twoPortAttribute[1] << "\n"
            << "Available Bias: " << availableBias[0] << availableBias[1] << "\n"
            << "Module Type: " << std::string(moduleType, 10) << "\n";
        return oss.str();
    }
};
 
// 站点标识符,默认使用本站
struct StationIdentifier {
    /*
     * [Network No.]
     * 0 表示本站
     * 1~239 表示普通网络号
     **/
 
     /*
      * [Station No.]
      * MELSECNET/H:1~64 表示其他站点,255 表示本站
      * CC-Link 系列网络的范围类似,区别在于站号的取值范围
      * MELSECNET/H             : 1~64(Other stations),255(Own station)
      * CC-Link                 : 0~63(Other stations),255(Own station)
      * CC-Link IE Controller   : 1~120(Other stations),255(Own station)
      * CC-Link IE Field        : 0~120(Other stations),255(Own station)
      * CC-Link IE TSN          : 0~120(Other stations),255(Own station)
      **/
 
      /*
       * 高 8 位(网络号): 指定设备所属的网络
       * 低 8 位(站点号): 指定设备在网络中的编号
       * 用一个参数传递设备的网络号和站点号时: nSt = station.nStNo | ((station.nNetNo << 8) & 0xFF00);
       **/
 
    short nNetNo = 0;    // 网络编号:PLC所连接的网络编号,0表示默认网络
    short nStNo = 255;   // 站点编号:指定与PLC连接的站点编号,255通常表示广播或所有站点
 
    // 自定义构造函数,覆盖默认值
    explicit StationIdentifier(const short net, const short st) : nNetNo(net), nStNo(st) {}
 
    StationIdentifier() 
    {
        nNetNo = 0;
        nStNo = 255;
    }
 
    // 将“网络号”和“站点号”组合成一个最终编码
    short StationIdentifier::toNetworkStationCode() const {
        return static_cast<short>(nStNo | ((nNetNo << 8) & 0xFF00));
    }
 
    // 重载 < 运算符(用于排序或比较,通常用于 map 或 set 中作为 key)
    bool operator<(const StationIdentifier& other) const {
        return std::tie(nNetNo, nStNo) <
            std::tie(other.nNetNo, other.nStNo);
    }
 
    // 重载 == 运算符(用于相等比较)
    bool operator==(const StationIdentifier& other) const {
        return std::tie(nNetNo, nStNo) ==
            std::tie(other.nNetNo, other.nStNo);
    }
 
    // 重载 = 运算符(用于赋值)
    StationIdentifier& operator=(const StationIdentifier& other) {
        if (this != &other) {
            nNetNo = other.nNetNo;
            nStNo = other.nStNo;
        }
        return *this;
    }
};
 
// 板状态
struct BoardStatus {
    short nStationValue = 0;    // 站号的设备值 (buf[0])
    short nGroupValue = 0;      // 组 No. 的设备值 (buf[1])
    short nNetworkValue = 0;    // 网络 No. 的设备值 (buf[2])
    short nReserved1 = 0;       // 保留字段 (buf[3])
    short nReserved2 = 0;       // 保留字段 (buf[4])
    short nReserved3 = 0;       // 保留字段 (buf[5])
 
    // 将数组映射到结构体
    static BoardStatus fromBuffer(const short buf[6]) {
        return {
            buf[0],
            buf[1],
            buf[2],
            buf[3],
            buf[4],
            buf[5]
        };
    }
 
    // 将结构体内容映射到数组
    void toBuffer(short buf[6]) const {
        buf[0] = nStationValue;
        buf[1] = nGroupValue;
        buf[2] = nNetworkValue;
        buf[3] = nReserved1;
        buf[4] = nReserved2;
        buf[5] = nReserved3;
    }
 
    // 调试输出
    std::string toString() const {
        std::ostringstream oss;
        oss << "Station Value: " << nStationValue << "\n"
            << "Group Value: " << nGroupValue << "\n"
            << "Network Value: " << nNetworkValue << "\n"
            << "Reserved1: " << nReserved1 << "\n"
            << "Reserved2: " << nReserved2 << "\n"
            << "Reserved3: " << nReserved3 << "\n";
        return oss.str();
    }
};
 
// 事件详情
struct EventDetails {
    short nEventNo;                      // 发生的事件号
    std::array<short, 4> details;         // 存储事件详情信息
 
    // 解析事件详情,返回格式化字符串
    std::string toString() const {
        std::ostringstream oss;
        oss << "Details[0]: " << details[0] << ", "
            << "Details[1]: " << details[1] << ", "
            << "Details[2]: " << details[2] << ", "
            << "Details[3]: " << details[3];
        return oss.str();
    }
};
 
// SoftElement 结构体定义
struct SoftElement {
    short nType;         // 软元件类型
    short nElementCount; // 点数
    long nStartNo;       // 起始软元件编号
};
 
// 错误信息
struct ErrorInfo {
    int nErrorCode = 0;              // 错误码
    std::string strErrorMessageCn;   // 中文描述
    std::string strErrorMessageEn;   // 英文描述
 
    // 将结构体序列化为字符串
    std::string toString() const {
        std::ostringstream oss;
        oss << nErrorCode << "|" << strErrorMessageCn << "|" << strErrorMessageEn;
        return oss.str();
    }
 
    // 从字符串反序列化为结构体
    static ErrorInfo fromString(const std::string& line) {
        ErrorInfo info;
        std::istringstream iss(line);
        std::string token;
 
        // 使用分隔符 "|" 解析字符串
        std::getline(iss, token, '|');
        info.nErrorCode = std::stoi(token);
 
        std::getline(iss, token, '|');
        info.strErrorMessageCn = token;
 
        std::getline(iss, token, '|');
        info.strErrorMessageEn = token;
 
        return info;
    }
};
 
using BitContainer = std::vector<bool>;            // 每个元素存储 1  位
using WordContainer = std::vector<uint16_t>;    // 每个元素存储 16 位
using DWordContainer = std::vector<uint32_t>;    // 每个元素存储 32 位
 
// CPerformanceMelsec 类声明
class CPerformanceMelsec {
public:
    // 获取最近的错误信息
    std::string GetLastError() const;
 
    // 错误信息加载与保存接口
    static bool LoadErrorInfoFromFile(const std::string& filename);  // 从文件加载错误信息
    static bool SaveErrorInfoToFile(const std::string& filename);    // 保存错误信息到文件
 
    // 连接/断开
    int Connect(short nChannel, short nMode = -1);
    int Disconnect();
 
    // 初始化可编程控制器软元件信息表
    int InitializeController();
 
    //    获取版本信息
    int GetBoardVersion(BoardVersion& version);
 
    // 板复位
    int BoardReset();
 
    // 板LED读取
    int ReadBoardLed(std::vector<short>& vecLedBuffer);
 
    // 读取目标站点CPU类型
    int ReadCPUCode(const StationIdentifier& station, short& nCPUCode);
 
    // 板模式获取/设置
    int SetBoardMode(short nMode);
    int GetBoardMode(short& nMode);
 
    // 获取板状态
    int GetBoardStatus(BoardStatus& status);
 
    // 读写数据
    int ReadData(const StationIdentifier& station, long nDevType, long nDevNo, long nSize, std::vector<short>& vecData);
    int ReadBitData(const StationIdentifier& station, DeviceType enDevType, short nDevNo, short nBitCount, BitContainer& vecData);
    int ReadWordData(const StationIdentifier& station, DeviceType enDevType, short nDevNo, short nWordCount, WordContainer& vecData);
    int ReadDWordData(const StationIdentifier& station, DeviceType enDevType, short nDevNo, short nDWordCount, DWordContainer& vecData);
    int WriteData(const StationIdentifier& station, long nDevType, long nDevNo, long nSize, short* pData);
    int WriteBitData(const StationIdentifier& station, DeviceType enDevType, short nDevNo, const BitContainer& vecData);
    int WriteWordData(const StationIdentifier& station, DeviceType enDevType, short nDevNo, const WordContainer& vecData);
    int WriteDWordData(const StationIdentifier& station, DeviceType enDevType, short nDevNo, const DWordContainer& vecData);
 
    // 扩展读写数据
    long ReadDataEx(const StationIdentifier& station, long nDevType, long nDevNo, long nSize, std::vector<char>& vecData);
    long ReadBitDataEx(const StationIdentifier& station, DeviceType enDevType, long nDevNo, long nBitCount, BitContainer& vecData);
    long ReadWordDataEx(const StationIdentifier& station, DeviceType enDevType, long nDevNo, long nWordCount, WordContainer& vecData);
    long ReadDWordDataEx(const StationIdentifier& station, DeviceType enDevType, long nDevNo, long nDWordCount, DWordContainer& vecData);
    long WriteDataEx(const StationIdentifier& station, long nDevType, long nDevNo, const std::vector<char>& vecData);
    long WriteBitDataEx(const StationIdentifier& station, DeviceType enDevType, long nDevNo, const BitContainer& vecData);
    long WriteWordDataEx(const StationIdentifier& station, DeviceType enDevType, long nDevNo, const WordContainer& vecData);
    long WriteDWordDataEx(const StationIdentifier& station, DeviceType enDevType, long nDevNo, const DWordContainer& vecData);
 
    // 扩展软元件随机读写(支持多个软元件)
    long ReadRandomDataEx(const StationIdentifier& station, const std::vector<SoftElement>& vecSoftElements, std::vector<char>& vecData);
    long WriteRandomDataEx(const StationIdentifier& station, const std::vector<SoftElement>& vecSoftElements, const std::vector<char>& vecData);
 
    // 远程设备站/远程站的缓冲存储器读写
    long ReadRemoteBuffer(const StationIdentifier& station, long nOffset, long nSize, std::vector<char>& vecData);
    long WriteRemoteBuffer(const StationIdentifier& station, long nOffset, const std::vector<char>& vecData);
    long ReadRemoteBufferByIp(const std::string& strIP, long nOffset, long nSize, std::vector<char>& vecData);
    long WriteRemoteBufferByIp(const std::string& strIP, long nOffset, const std::vector<char>& vecData);
 
    // 设置/复位对象站的指定位软元件
    int SetBitDevice(const StationIdentifier& station, DeviceType enDevType, short nDevNo);
    int ResetBitDevice(const StationIdentifier& station, DeviceType enDevType, short enDevNo);
 
    // 扩展设置/复位对象站的指定位软元件
    long SetBitDeviceEx(const StationIdentifier& station, DeviceType enDevType, long nDevNo);
    long ResetBitDeviceEx(const StationIdentifier& station, DeviceType enDevType, long nDevNo);
 
    // 执行对象站的CPU
    int ControlCPU(const StationIdentifier& station, ControlCode enControlCode);
 
    // 事件等待,vecEventNumbers[0, 64],nTimeoutMs[-1, 2147483647]
    // 同时发生了多个事件的情况下,首先检测出其中一个事件。 再次执行了本函数的情况下检测出其它事件。
    int WaitForBoardEvent(std::vector<short> vecEventNumbers, int nTimeoutMs, EventDetails& details);
 
private:
    // 锁定与解锁(多线程同步保护)
    void Lock() { m_mtx.lock(); }
    void Unlock() { m_mtx.unlock(); }
 
protected:
    // 构造函数/析构函数
    explicit CPerformanceMelsec(BoardType enBoardType);
    virtual ~CPerformanceMelsec();
 
    // 辅助函数
    void UpdateLastError(int nCode);                                 // 更新最近的错误信息
    int ValidateStation(const StationIdentifier& station) const;     // 检查连接状态和站点参数有效性
    int ValidateStationAndSize(const StationIdentifier& station, short nCount) const;
 
    // 静态辅助函数
    static void Delay(unsigned int nDelayMs);                        // 延时,并且转发窗口消息
    static BoardType FindBoardTypeByChannel(int nChannel);            // 查找板块类型
    static short CombineStation(const StationIdentifier& station);  // 合并网络号和站点号
    static short CalculateDeviceType(const StationIdentifier& station, DeviceType enDevType); // 计算软元件类型
 
    // IP转换
    static bool ConvertIpStringToUint32(const std::string& strIP, uint32_t& nIP);
 
    // 容器转换
    static void ConvertCharToShort(const std::vector<char>& vecChar, std::vector<short>& vecShort);
    static void ConvertShortToChar(const std::vector<short>& vecShort, std::vector<char>& vecChar);
    static void ConvertUint8ToShort(const std::vector<uint8_t>& vecUint8, std::vector<short>& vecShort);
    static void ConvertShortToUint8(const std::vector<short>& vecShort, std::vector<uint8_t>& vecUint8);
    static void ConvertUint32ToShort(const std::vector<uint32_t>& vecUint32, std::vector<short>& vecShort);
    static void ConvertShortToUint32(const std::vector<short>& vecShort, std::vector<uint32_t>& vecUint32);
 
    // 模板辅助函数
    template <typename T>
    int ValidateStationAndData(const StationIdentifier& station, const std::vector<T>& vecData);
 
    template <typename T, typename U>
    void ConvertLowToHigh(const std::vector<T>& vecLow, std::vector<U>& vecHigh);
 
    template <typename T, typename U>
    void ConvertHighToLow(const std::vector<T>& vecHigh, std::vector<U>& vecLow);
 
    // 成员变量
    std::mutex m_mtx;                       // 互斥锁保护
    BoardType m_enBoardType;                // 板块类型
    long m_nPath;                           // 通信路径
    std::atomic<bool> m_bConnected;         // 是否已连接
    std::string m_strLastError;             // 最近一次错误信息
 
    // 静态成员变量
    static std::unordered_map<int, std::string> m_mapError; // 错误码映射表
};
 
#endif // PERFORMANCE_MELSEC_H