问题描述
ExcelGenerator.WriteToFile假定报文属性GenMsgCycleTime始终存储在IntegerCustomProperty` 中。
但 DBC 文件可以将 GenMsgCycleTime 定义为 FLOAT 类型。遇到这种文件时,IntegerCustomProperty 为 null,Excel 导出过程会触发 NullReferenceException。随后该异常又被转换为 WriteStatus.UnknownError,导致调用者无法看到真正的失败原因。
我在当前 master 分支中确认了这个问题:
提交:a736f3b850bb454268093b8c1a409627649393e8
文件:EasyDbc/Generators/ExcelGenerator.cs
相关代码:第 672~678 行
最小复现 DBC
VERSION ""
NS_ :
BS_:
BU_: ECU
BO_ 291 StatusMessage: 8 ECU
SG_ Status : 0|8@1+ (1,0) [0|255] "" ECU
BA_DEF_ BO_ "GenMsgCycleTime" FLOAT 0 3600000;
BA_ "GenMsgCycleTime" BO_ 291 100.0;
复现步骤
- 使用 EasyDbc 解析上面的 DBC。
- 检查报文的
GenMsgCycleTime 属性,此时应满足:
DataType == CustomPropertyDataType.Float
-FloatCustomProperty 已赋值
IntegerCustomProperty 为 null
- 使用解析得到的 DBC 调用
ExcelGenerator.WriteToFile。
- 检查该方法返回的状态。
实际结果
ExcelGenerator.WriteToFile 返回:
真正的异常来自下面这段代码:
GenMsgSendTypeValue.IntegerCustomProperty.Value
当 GenMsgCycleTime 被定义为 FLOAT 时,IntegerCustomProperty 为 null,因此这里会触发空引用异常。
期望结果
Excel 导出应该成功,并在周期列中写入 100 或 100.0。
生成器应根据 CustomPropertyDefinition.DataType 读取实际属性值,至少需要支持:
INT:读取 IntegerCustomProperty
HEX:读取 HexCustomProperty
FLOAT:读取 FloatCustomProperty
建议修复方式
可以按照属性定义的实际类型读取数值,例如:
string cycleTime = property.CustomPropertyDefinition.DataType switch
{
CustomPropertyDataType.Integer =>
property.IntegerCustomProperty?.Value.ToString(
CultureInfo.InvariantCulture),
CustomPropertyDataType.Hex =>
property.HexCustomProperty?.Value.ToString(
CultureInfo.InvariantCulture),
CustomPropertyDataType.Float =>
property.FloatCustomProperty?.Value.ToString(
CultureInfo.InvariantCulture),
_ => null,
};
table[currentLine, cycleTimeColumn.ColumnIndex] = cycleTime ?? "0";
建议使用 CultureInfo.InvariantCulture,避免导出的数值受到 Windows 区域设置和小数分隔符影响。
补充说明
ExtensionsAndHelpers.cs 中的 Message.CycleTime() 似乎也存在相同的“只支持 Integer”假设:
cycleTime = property.IntegerCustomProperty.Value;
建议同时检查并修复这两个调用位置。否则即使修复了 Excel 导出,其他调用 Message.CycleTime() 的代码在读取 FLOAT 或 HEX 类型的 GenMsgCycleTime 时,仍可能触发空引用异常。
问题描述