using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; namespace ZLGCANFD { public class ZLG_Msg { public int msg_type { get; set; } public uint msg_id { get; set; } public double msg_cyclic { get; set; } public byte msg_dlc { get; set; } public string msg_name { get; set; } public List signals { get; set; } = new List(); public string[] signal_Name { get; set; } // 适配 ZLG 的 CANFD 帧结构 (来自 2.txt) public CAN.ZCAN_CANFD_FRAME ACANFD; } public class DBCParse { // 存储多通道的消息数据库 public static List> MsgDatabase { get; set; } = Enumerable.Range(0, 12).Select(_ => new List()).ToList(); /// /// ZLG 专用解析逻辑:遍历 ZDBC 内部的消息链表并填充到 MsgDatabase /// /// ZDBC_Init 返回的句柄 /// 目标通道索引 public static void Parse(uint hDBC, int channel) { if (hDBC == ZDBC.INVALID_DBC_HANDLE) return; // 1. 初始化指针空间 int msgSize = Marshal.SizeOf(typeof(ZDBC.DBCMessage)); nint pMsg = Marshal.AllocHGlobal(msgSize); try { // 清空当前通道旧数据 MsgDatabase[channel].Clear(); // 2. 迭代获取所有消息 bool hasMessage = ZDBC.ZDBC_GetFirstMessage(hDBC, pMsg); while (hasMessage) { ZDBC.DBCMessage dbMsg = Marshal.PtrToStructure(pMsg); ZLG_Msg temp = new ZLG_Msg(); temp.msg_id = dbMsg.nID; temp.msg_name = Encoding.Default.GetString(dbMsg.strName).TrimEnd('\0'); temp.msg_dlc = (byte)dbMsg.nSize; temp.msg_cyclic = dbMsg.nCycleTime; temp.msg_type = dbMsg.nExtend; // 0-标准帧, 1-扩展帧 // 3. 处理信号 int sigCount = (int)dbMsg.nSignalCount; temp.signal_Name = new string[sigCount]; for (int i = 0; i < sigCount; i++) { var sig = dbMsg.vSignals[i]; temp.signals.Add(sig); temp.signal_Name[i] = Encoding.Default.GetString(sig.strName).TrimEnd('\0'); } // 4. 初始化对应的 ZLG 发送帧结构 (预设好 ID 和 DLC) temp.ACANFD = new CAN.ZCAN_CANFD_FRAME(); temp.ACANFD.can_id = dbMsg.nID; temp.ACANFD.len = (byte)dbMsg.nSize; temp.ACANFD.eff = dbMsg.nExtend; temp.ACANFD.data = new byte[64]; MsgDatabase[channel].Add(temp); // 获取下一条 hasMessage = ZDBC.ZDBC_GetNextMessage(hDBC, pMsg); } // 按 ID 排序 MsgDatabase[channel].Sort((a, b) => a.msg_id.CompareTo(b.msg_id)); } finally { // 释放内存 Marshal.FreeHGlobal(pMsg); } } /// /// 加载 DBC 的入口函数 /// public static int LoadDBC(string filePath, int[] channels, out uint databaseID) { // 初始化 databaseID = ZDBC.ZDBC_Init(0, 1); if (databaseID == ZDBC.INVALID_DBC_HANDLE) return -1; // 准备文件信息 ZDBC.FileInfo fileInfo = new ZDBC.FileInfo(); fileInfo.strFilePath = new byte[ZDBC._MAX_FILE_PATH_ + 1]; byte[] pathBytes = Encoding.Default.GetBytes(filePath); Array.Copy(pathBytes, fileInfo.strFilePath, Math.Min(pathBytes.Length, ZDBC._MAX_FILE_PATH_)); fileInfo.type = ZDBC.PROTOCOL_OTHER; fileInfo.merge = 0; // 加载文件 nint pFileInfo = Marshal.AllocHGlobal(Marshal.SizeOf(fileInfo)); Marshal.StructureToPtr(fileInfo, pFileInfo, false); bool success = ZDBC.ZDBC_LoadFile(databaseID, pFileInfo); Marshal.FreeHGlobal(pFileInfo); if (!success) { ZDBC.ZDBC_Release(databaseID); return -2; } // 解析到各通道 foreach (var ch in channels) { Parse(databaseID, ch); } return 0; } /// /// 卸载 DBC 并释放 ZDBC 句柄 /// public static int UnLoadDBC(uint? databaseID = null) { if (databaseID.HasValue && databaseID.Value != ZDBC.INVALID_DBC_HANDLE) { ZDBC.ZDBC_Release(databaseID.Value); } foreach (var list in MsgDatabase) { list.Clear(); } return 0; } } }