Qt 解析 DBC文件,获取DBC文件信息

使用Qt库解析DBC文件:

结构体:

struct SignalInfo_S
{
    QString SignalName;
    QString MsgName;
    int msgid{};
    double scale{};
    double offset{};
    int startbit{};
    int lenth{};
    int codetype{};
};

struct MsgInfo_S
{
    int MsgID{};
    QString MsgName;
    QString SendNodeName;
    int msgSendType{};
    int msgCycleTime{};
};

//解析文件函数

void CCanManager::LoadSignals(QString filename, QList<SignalInfo_S>& inputsiglist, QList<MsgInfo_S>& inputmsglist, \
    QList<SignalInfo_S>& outputsiglist, QList<MsgInfo_S>& outputmsglist)
{
#if 1
    //打开文件
    QFile dbc_file(filename);
    if (!dbc_file.open(QIODevice::ReadOnly))
    {
        return;
    }
    //每行读取数据
    QString linestr;
    int linecounter = 0;
    //记录当前解析msg信息
    MsgInfo_S msginfo = { 0 };
    bool isoutput = false;
    while (!dbc_file.atEnd())
    {
        linestr = dbc_file.readLine();
        bool ok;
        QString msgname;
        int msgid;
        if (linestr.startsWith("BO_"))
        {
            QStringList linelist = linestr.split(" ");
            msginfo.MsgID                = (linelist[1].toLongLong(&ok)) & 0x7FFFFFFF;
            msginfo.MsgName          = linelist[2].remove(":");
            msginfo.SendNodeName = linelist[4].remove(":").trimmed();
            QString strlast                 = linelist.last();
            if (strlast.contains(NODENAME))
            {
                outputmsglist.append(msginfo);
                isoutput = true;
            }
            else
            {
                isoutput = false;
            }
        }
        else if (linestr.startsWith(" SG_ "))
        {
            QStringList linelist = linestr.trimmed().split(" ");
            bool contain = false;
            for (int i = 0; i < inputmsglist.count(); i++)
            {
                if (inputmsglist[i].MsgID        == msginfo.MsgID && \
                    inputmsglist[i].SendNodeName == msginfo.SendNodeName && \
                    inputmsglist[i].MsgName      == msginfo.MsgName)
                {
                    contain = true;
                    break;
                }
            }
            for (int i = 0; i < outputmsglist.count(); i++)
            {
                if (outputmsglist[i].MsgID == msginfo.MsgID && \
                    outputmsglist[i].SendNodeName == msginfo.SendNodeName && \
                    outputmsglist[i].MsgName == msginfo.MsgName)
                {
                    contain = true;
                    break;
                }
            }
            if ((linelist.last().contains(NODENAME)|| linelist.last().contains("Vector__XXX")) && (!contain))
            {
                inputmsglist.append(msginfo);
            }
            SignalInfo_S siginfo;
            QStringList offsesacle  = linelist[4].remove("(").remove(")").split(",");
            siginfo.scale                 = offsesacle[0].toDouble();
            siginfo.offset               = offsesacle[1].toDouble();
            QStringList sblenmi     = linelist[3].replace("|", ".").replace("@", ".").remove("+").split(".");
            siginfo.startbit            = sblenmi[0].toInt();
            siginfo.lenth               = sblenmi[1].toInt();
            siginfo.codetype         = sblenmi[2].toInt();
            siginfo.msgid             = msginfo.MsgID;
            siginfo.MsgName       = msginfo.MsgName;
            siginfo.SignalName     = linelist[1];
            if (isoutput)
            {
                outputsiglist.append(siginfo);
            }
            else
            {
                if (linelist.last().contains(NODENAME) || linelist.last().contains("Vector__XXX"))
                    inputsiglist.append(siginfo);
            }
        }
        else if (linestr.startsWith("BA_ "))
        {
            QStringList linelist = linestr.split(" ");
            if (linestr.contains("\"GenMsgSendType\""))
            {
                int msgid = (linelist[3].toLongLong(&ok, 10)) & 0x7FFFFFFF;
                for (int i = 0; i < inputmsglist.count(); i++)
                {
                    if (inputmsglist[i].MsgID == msgid)
                    {
                        inputmsglist[i].msgSendType = linelist[4].remove(";").trimmed().toInt();
                        break;
                    }
                }
            }
            else if (linestr.contains("\"GenMsgCycleTime\""))
            {
                int msgid = (linelist[3].toLongLong(&ok, 10)) & 0x7FFFFFFF;
                for (int i = 0; i < inputmsglist.count(); i++)
                {
                    if (inputmsglist[i].MsgID == msgid)
                    {
                        inputmsglist[i].msgCycleTime = linelist[4].remove(";").trimmed().toInt();
                        break;
                    }
                }
            }
        }
    }

  • 7
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt C++中,可以使用第三方库来解析DBC文件。比如,可以使用Canlib库中提供的DBC解析功能,该库是Vector公司开发的CAN协议栈,支持多种CAN总线接口。 以下是使用Canlib库解析DBC文件的示例代码: ```c++ #include <canlib.h> #include <iostream> int main() { canInitializeLibrary(); // 打开DBC文件 canDatabaseHandle dbc = canOpenDbcFile("example.dbc"); // 获取所有的消息 canDatabaseMessage* messages; int messageCount = canGetMessageCount(dbc); messages = new canDatabaseMessage[messageCount]; canGetMessages(dbc, messages, messageCount); // 遍历消息,获取信号信息 for (int i = 0; i < messageCount; i++) { canDatabaseMessage message = messages[i]; std::cout << "Message ID: " << message.id << std::endl; // 获取消息中的所有信号 canDatabaseSignal* signals; int signalCount = canGetSignalCountInMessage(dbc, message.id); signals = new canDatabaseSignal[signalCount]; canGetSignalsInMessage(dbc, message.id, signals, signalCount); // 遍历信号,获取信号信息 for (int j = 0; j < signalCount; j++) { canDatabaseSignal signal = signals[j]; std::cout << " Signal Name: " << signal.name << std::endl; std::cout << " Signal Start Bit: " << signal.startBit << std::endl; std::cout << " Signal Bit Length: " << signal.bitLength << std::endl; std::cout << " Signal Factor: " << signal.factor << std::endl; std::cout << " Signal Offset: " << signal.offset << std::endl; std::cout << " Signal Unit: " << signal.unit << std::endl; } delete[] signals; } delete[] messages; // 关闭DBC文件 canCloseDbcFile(dbc); canUnloadLibrary(); return 0; } ``` 在上面的示例代码中,首先使用`canOpenDbcFile()`函数打开DBC文件,然后使用`canGetMessages()`函数获取所有的消息信息,再使用`canGetSignalsInMessage()`函数遍历每个消息中的所有信号信息。对于每个信号,可以获取其名称、起始位、位宽、系数、偏移量和单位等信息。最后,使用`canCloseDbcFile()`函数关闭DBC文件。 需要注意的是,使用Canlib库需要安装Vector公司提供的CAN驱动程序。另外,Canlib库也提供了其他的CAN相关功能,比如CAN总线的读写和过滤等操作,可以根据实际需求进行调用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值