使用GVariant实现数据的序列化处理

本文详细介绍了如何利用GVariant库进行大规模数据的序列化与反序列化过程,包括数据结构定义、序列化代码实现、序列化文件的创建与读取,以及基于此方式的数据在不同进程间的高效传输。通过实例展示了如何优化数据传输性能,适用于复杂应用环境。

内存中的大量数据如果要固化或跨进程传输,需要对数据进行序列化处理。使用GVariant除了可以描述数据自身的结构之外,还可以很容易的实现数据的序列化。下面的例子完成了一个自定义的5000条数据的序列化与恢复的过程:
1. 序列化5000条数据,数据内容是以字典方式存储的一个数据结构

#include <stdio.h>
#include <stdlib.h>
#include <glib.h>

/*
 * ===  FUNCTION  ======================================================================
 *         Name:  main
 *  Description:
 * =====================================================================================
 */
int main ( int argc, char *argv[] )
{
    int i;
    GVariant * _playlist;
    GVariantBuilder * _builder  =   g_variant_builder_new( G_VARIANT_TYPE( "av" ));
    gconstpointer _data;
    FILE * _fp;
    gsize _size;

    for( i = 0; i < 5000; i ++ )
    {
        GVariant * _item;
        GVariantBuilder * _itemBuilder  =   g_variant_builder_new( G_VARIANT_TYPE( "a{ss}" ));

        g_variant_builder_add( _itemBuilder, "{ss}", "location", "file:///tmp/00000001/1.mp3" );
        g_variant_builder_add( _itemBuilder, "{ss}", "name", "2.mp3" );
        g_variant_builder_add( _itemBuilder, "{ss}", "type", "mp3" );

        _item   =   g_variant_builder_end( _itemBuilder );

        g_variant_builder_add( _builder, "v", _item );
    }

    _playlist   =   g_variant_builder_end( _builder );

    _data   =   g_variant_get_data( _playlist );
    _size   =   g_variant_get_size( _playlist );

    _fp =   fopen( "/tmp/a.mhpl", "w" );

    fwrite( _data, _size, 1, _fp );

    fclose( _fp );

    g_variant_builder_unref( _builder );
    g_variant_unref( _playlist );

    return 0;
}               /* ----------  end of function main  ---------- */
2. 反序列化,将序列化的数据恢复后打印出来
#include <stdio.h>
#include <stdlib.h>
#include <glib.h>
/*
 * ===  FUNCTION  ======================================================================
 *         Name:  main
 *  Description:
 * =====================================================================================
 */
int main ( int argc, char *argv[] )
{
    FILE * _fp  =   fopen( "/tmp/a.mhpl", "r" );
    gsize _size;
    GVariant * _playlist;
    gpointer _data;
    GVariantIter * _iter;
    GVariant * _item;

    fseek( _fp, 0, SEEK_END );

    _size   =   ftell( _fp );

    _data   =   g_malloc0( _size );

    rewind( _fp );

    fread( _data, _size, 1, _fp );

    fclose( _fp );

    _playlist   =   g_variant_new_from_data( G_VARIANT_TYPE( "av" ), _data,
            _size, TRUE, NULL, NULL );

    _iter   =   g_variant_iter_new( _playlist );

    while( g_variant_iter_next( _iter, "v", &_item ))
    {
        gchar * _location, * _name, * _type;

        g_variant_lookup( _item, "location", "s", &_location );
        g_variant_lookup( _item, "name", "s", &_name );
        g_variant_lookup( _item, "type", "s", &_type );

        g_message( "%s, %s, %s", _location, _name, _type );

        g_variant_unref( _item );
        g_free( _location );
        g_free( _name );
        g_free( _type );
    }

    g_variant_iter_free( _iter );

    g_variant_unref( _playlist );

    return 0;
}               /* ----------  end of function main  ---------- */
3. 对于基于DBus方式实现的IPC,传输大量数据存在性能瓶颈。因此,可以基于上面的方式,将数据序列化后,由pipe或socket传输的方式在进程间传递,在性能上可以获得极大提升


#include "pch.h" #include "MESInterface.h" #include "Loger.h" extern CGlobalVariant m_GVariant; // 全局变量 extern CGlobalFunction m_GFunction; // 全局函数 extern Loger m_Loger; // 全局Log类 extern CActionFlow m_GActionFlow; // 动作流程 extern CDlgDevError m_dlgError; MESInterface* MESInterface::m_pInstance = nullptr; MESInterface * MESInterface::GetInstance() { static CCriticalSection cs; CriticalSectionLock lock(cs); // 使用我们之前定义的 RAII 锁 if (m_pInstance == nullptr) // 错误:m_pInstance 未声明 { m_pInstance = new MESInterface(); } return m_pInstance; } void MESInterface::PostTask(TaskType type, const CString & param) { TaskItem* pItem = new TaskItem(); pItem->type = type; pItem->param = param; { //CriticalSectionLock lock(m_cs); // 使用自定义锁 m_taskList.AddTail(pItem); } m_taskEvent.SetEvent(); // 触发事件 } UINT MESInterface::WorkerThreadProc(LPVOID pParam) { MESInterface* pThis = (MESInterface*)pParam; while (!pThis->m_bStopThread) { DWORD dwWait = WaitForSingleObject(pThis->m_taskEvent.m_hObject, INFINITE); if (dwWait != WAIT_OBJECT_0) continue; if (pThis->m_bStopThread) break; TaskItem* pItem = nullptr; { CriticalSectionLock lock(pThis->m_cs); // 使用自定义锁 if (!pThis->m_taskList.IsEmpty()) { pItem = pThis->m_taskList.RemoveHead(); } } if (pItem) { pThis->ProcessTask(pItem); delete pItem; } } return 0; } void MESInterface::ProcessTask(TaskItem * pItem) { switch (pItem->type) { case TASK_CHECK: ExecuteCheck(m_GFunction.CString2String(pItem->param)); break; case TASK_EVENT_DEVICE_STATE_CHANGED: ExecuteDeviceStop(static_cast<StopCode>(_ttoi(pItem->param))); break; } } int MESInterface::ExecuteCheck(string sn) { CriticalSectionLock lock(m_cs); // 线程安全调用 MesJTInfo info; info.WP = QString::fromLocal8Bit(m_GVariant.m_MesConfigFile->WP.c_str()); info.JZ = QString::fromLocal8Bit(m_GVariant.m_MesConfigFile->JZ.c_str()); info.User = QString::fromLocal8Bit(m_GVariant.m_MesConfigFile->User.c_str()); info.Line = QString::fromLocal8Bit(m_GVariant.m_MesConfigFile->Line.c_str()); info.Machine = QString::fromLocal8Bit(m_GVariant.m_MesConfigFile->Machine.c_str()); info.OffLine = m_GVariant.m_MesConfigFile->OffLine; info.Tray = QString::fromLocal8Bit(m_GVariant.m_MesConfigFile->Tray.c_str()); info.Barcodes.append(QString::fromLocal8Bit(sn.c_str())); QString jsonString = info.toJsonString(); Response res = SendMesJTInfo(static_cast<string>(jsonString.toLocal8Bit())); if (res.Code == 0 || res.Result == "OK") { return 1; } else { addErrInfo(static_cast<string>(res.Msg.toLocal8Bit())); return -1; } return 0; } void MESInterface::ExecuteDeviceStop(StopCode state) { CriticalSectionLock lock(m_cs); // 线程安全调用 MesEquStop maState; string eventDesc = ""; int deviceStatus = 0; switch (state) { case Waiting: eventDesc = "待机"; deviceStatus = 1; break; case Wroking: eventDesc = "作业"; deviceStatus = 2; break; case Faulted: eventDesc = "故障"; deviceStatus = 3; break; case Stopped: eventDesc = "关机"; deviceStatus = 4; break; default: eventDesc = "开机"; deviceStatus = 0; break; } maState.StopCode = deviceStatus; maState.StopType = QString::fromLocal8Bit(eventDesc.c_str()); maState.Machine = QString::fromLocal8Bit(m_GVariant.m_MesConfigFile->Machine.c_str()); maState.StartTime = QDateTime::currentDateTime(); maState.JZ = QString::fromLocal8Bit(m_GVariant.m_MesConfigFile->JZ.c_str()); maState.Line = QString::fromLocal8Bit(m_GVariant.m_MesConfigFile->Line.c_str()); maState.User = QString::fromLocal8Bit(m_GVariant.m_MesConfigFile->User.c_str()); QString jsonString = maState.toJsonString(); Response res = SendMesEquStop(static_cast<string>(jsonString.toLocal8Bit())); if (res.Code == 0 || res.Result == "OK") { return; } else { addErrInfo(static_cast<string>(res.Msg.toLocal8Bit())); return; } } QString convertSimple(const QString& input) { if (input.length() != 17) return input; // 确保长度正确 QString year = input.mid(0, 4); QString month = input.mid(4, 2); QString day = input.mid(6, 2); QString time = input.mid(9, 8); // 提取时间部分 return QString("%1-%2-%3 %4").arg(year, month, day, time); } int MESInterface::updataMes(TestData testData) { MesMTF mesInfo; auto MTFvariantMap = testData.toVariantMap(); // 这里拿到了OrderedVariantMap的值 QString MTFString = "{"; for (const QString& key : MTFvariantMap.keys()) { QVariant variant = MTFvariantMap[key]; QString value = variant.toString(); MTFString.append("\"" + key + "\":\"" + value + "\","); } MTFString.chop(1); MTFString.append("}"); MTF Data; Data.Barcode = testData.Barcode; Data.ST = convertSimple(testData.Basic.Time); if ("PASS" == testData.Result.Aggregate.trimmed() || "BEST" == testData.Result.Aggregate.trimmed()) { Data.Result = "OK"; } else { Data.Result = "NG"; } Data.MTF = MTFString; auto DatavariantMap = Data.toVariantMap(); QString DataString = "[{"; for (const QString& key : DatavariantMap.keys()) { QVariant variant = DatavariantMap[key]; QString value = variant.toString(); if (key == "MTF") { DataString.append("\"" + key + "\":" + value + ","); } else { DataString.append("\"" + key + "\":\"" + value + "\","); } } DataString.chop(1); DataString.append("}]"); mesInfo.Num = 1; mesInfo.JZ = QString::fromLocal8Bit(m_GVariant.m_MesConfigFile->JZ.c_str()); mesInfo.User = QString::fromLocal8Bit(m_GVariant.m_MesConfigFile->User.c_str()); mesInfo.Line = QString::fromLocal8Bit(m_GVariant.m_MesConfigFile->Line.c_str()); mesInfo.Machine = QString::fromLocal8Bit(m_GVariant.m_MesConfigFile->Machine.c_str()); mesInfo.Tray = QString::fromLocal8Bit(m_GVariant.m_MesConfigFile->Tray.c_str()); mesInfo.OffLine = m_GVariant.m_iFrontRunMode == 0 ? 1 : 0; mesInfo.Data = DataString; QString jsonString = "{"; auto mesinfo = mesInfo.toVariantMap(); for (const QString& key : mesinfo.keys()) { QVariant variant = mesinfo[key]; QString value = variant.toString(); if (key == "Data") { jsonString.append("\"" + key + "\":" + value + ","); } else { jsonString.append("\"" + key + "\":\"" + value + "\","); } } jsonString.chop(1); jsonString.append("}"); Response res = SendMesEquStop(static_cast<string>(jsonString.toLocal8Bit())); if (res.Code == 0 || res.Result == "OK") { return 1; } else { addErrInfo(static_cast<string>(res.Msg.toLocal8Bit())); return -1; } return 0; } void MESInterface::PullMes() { CriticalSectionLock lock(m_cs); // ✅ 加锁 sSC_PullMes.Init(); updataRun = true; while (true) { int iRtn = FL_PullMes(); if (-1 == iRtn) { updataRun = false; break; } Sleep(5); } } int MESInterface::FL_PullMes() { int iRtn = 0; switch (sSC_PullMes.nStep) { case 0: addInfo(sSC_PullMes, 5, "开始巡检MES目录", true); return 0; case 5: iRtn = checkFolder(); if (-1 == iRtn) { addInfo(sSC_PullMes, ST_ERR, "巡检MES目录失败"); } if (1 == iRtn) { sSC_PullMes.nStep = 10; } else { sSC_PullMes.SetDelay(5, 1000); } return 0; case 10: if (m_File.checkFileExist(m_destinationFolder, m_currentFileNames)) { sSC_PullMes.nStep = 15; } else { addInfo(sSC_PullMes, ST_ERR, "检查MES文件是否存在失败"); } return 0; case 15: if (m_bufferFileNames.size() == 0) { sSC_PullMes.nStep = ST_END; } else { sSC_PullMes.nStep = 20; } return 0; case 20: if (m_iItemIndex <= m_bufferFileNames.size() - 1) { m_qstrRemoveFile = m_bufferFileNames[m_iItemIndex]; QString tempFile = m_destinationFolder + "\\" + m_qstrRemoveFile; if (deserializeFromJsonFile(tempFile, m_MesInfo)) { m_GVariant.configItemFile->copyToTestData(m_MesInfo); if (m_MesInfo.Barcode == "" || m_MesInfo.Barcode.length() < 5) { m_iItemIndex = 0;//将索引归零 addInfo(sSC_PullMes, 15, "条码长度小于5:条码为" + (string)m_MesInfo.Barcode.toLocal8Bit()); m_bufferFileNames.removeOne(m_bufferFileNames[m_iItemIndex]); } else { m_iItemIndex++; addInfo(sSC_PullMes, 25, "准备上传单角度数据"); } } else { addInfo(sSC_PullMes, ST_ERR, "文件" + (string)tempFile.toLocal8Bit() + "json序列化失败"); } } else { addInfo(sSC_PullMes, ST_END, "缓存文件已上传完毕"); } return 0; case 25: iRtn = updataMes(m_MesInfo); if (-1 == iRtn) { sSC_PullMes.nStep = ST_ERR; } if (1 == iRtn) { //清空列表中的 m_bufferFileNames.removeOne(m_qstrRemoveFile); m_iItemIndex = 0;//将索引归零 addInfo(sSC_PullMes, 15, "单角度上传完成,开始缓存新MES数据"); } return 0; case ST_DELAY: if (GetTickCount() - sSC_PullMes.dwStart >= sSC_PullMes.dwDelay) { sSC_PullMes.nStep = sSC_PullMes.nStepNext; } return 0; case ST_ERR: return -1; case ST_END: sSC_PullMes.ulCountEnd = m_GFunction.GetCPUPerformanceCounter(); sSC_PullMes.dCycleTime = (sSC_PullMes.ulCountEnd - sSC_PullMes.ulCountStart) / 1000000.0; sSC_PullMes.AddCTRecordEnd(m_GActionFlow.m_iRecordCycleTime, "sSC_PullMes over, CycleTime:", sSC_PullMes.dCycleTime); sSC_PullMes.Init(); return 1; } return 0; } void MESInterface::StartWorkerThread() { if (m_pWorkerThread == nullptr) { m_pWorkerThread = AfxBeginThread(WorkerThreadProc, this); } } void MESInterface::StopWorkerThread() { if (m_pWorkerThread != nullptr) { m_bStopThread = true; m_taskEvent.SetEvent(); // 唤醒线程退出 WaitForSingleObject(m_pWorkerThread->m_hThread, INFINITE); m_pWorkerThread = nullptr; } } MESInterface::MESInterface() { updataRun = false; StartWorkerThread(); } MESInterface::~MESInterface() { StopWorkerThread(); } // 请求镜头过线情况接口 /// http://10.93.2.17:8083/datasnap/rest/THttp1/MesJTInfo Response MESInterface::SendMesJTInfo(string info) { string host = m_GVariant.m_MesConfigFile->Host; int port = m_GVariant.m_MesConfigFile->Port; string path = m_GVariant.m_MesConfigFile->Check; string username = m_GVariant.m_MesConfigFile->UserName; string password = m_GVariant.m_MesConfigFile->PassWord; Response resp = Send(info, host, port, path, username, password); if (SUCCESS == resp.Code) { return ParseRcv(static_cast<string>(resp.Msg.toLocal8Bit())); } return resp; } // 工序接口- MTF检查 /// http://10.93.2.17:8083/datasnap/rest/THttp1/MesZZ Response MESInterface::SendMesMTF() { string host = m_GVariant.m_MesConfigFile->Host; int port = m_GVariant.m_MesConfigFile->Port; string path = m_GVariant.m_MesConfigFile->Save; string username = m_GVariant.m_MesConfigFile->UserName; string password = m_GVariant.m_MesConfigFile->PassWord; string info = ""; Response resp = Send(info, host, port, path, username, password); if (SUCCESS == resp.Code) { return ParseRcv(static_cast<string>(resp.Msg.toLocal8Bit())); } return resp; } // 其它接口-设备异常上报 /// http://10.93.2.17:8083/datasnap/rest/THttp1/MesEquStop Response MESInterface::SendMesEquStop(string info) { string host = m_GVariant.m_MesConfigFile->Host; int port = m_GVariant.m_MesConfigFile->Port; string path = m_GVariant.m_MesConfigFile->DeviceInfoCollerct; string username = m_GVariant.m_MesConfigFile->UserName; string password = m_GVariant.m_MesConfigFile->PassWord; Response resp = Send(info, host, port, path, username, password); if (SUCCESS == resp.Code) { return ParseRcv(static_cast<string>(resp.Msg.toLocal8Bit())); } return resp; } int MESInterface::addInfo(string & info) { if (m_logInfo == info) { return 1; } m_logInfo = info; m_Loger.RecordLogMes(m_logInfo); // 发送消息,传递快照指针 if (NULL != m_GActionFlow.m_hwdMainView) { // 使用PostMessage CString* pMsg = new CString(CA2CT(info.c_str())); ::SendMessage(m_GActionFlow.m_hwdMainView, WM_MESINFO, (WPARAM)pMsg, 0); } return 0; } int MESInterface::addInfo(StepCtrl & crtl, int next, string info, bool blag) { addInfo(info); crtl.nStep = next; if (blag) { crtl.ulCountStart = m_GFunction.GetCPUPerformanceCounter(); crtl.InitRecordString(); } if (next == ST_ERR) { addErrInfo(info); } return 0; } int MESInterface::addErrInfo(string info) { info = "MES" + info; m_GActionFlow.LightOpenRed(); m_dlgError.SetError(info); m_Loger.RecordLogError(info); //m_gMes.DeviceStateChanged(DeviceState::Faulted); 不能用,MES服务端出现问题后不能再调用,会导致死循环 AfxMessageBox(m_GFunction.String2CString(info), MB_OK | MB_ICONSTOP | MB_SYSTEMMODAL); m_GActionFlow.LightOpenYellow(); return 0; } void MESInterface::Connect() { CriticalSectionLock lock(m_cs); if (m_GVariant.m_MesConfigFile->Enable == 0) { m_connectionState = ConnectionState::Disconnected; return; } // 已连接且目标相同则直接返回 if (m_pConnection && m_connectionState == ConnectionState::Connected) { if (m_cachedHost == m_GVariant.m_MesConfigFile->Host && m_cachedPort == m_GVariant.m_MesConfigFile->Port) { return; } } m_connectionState = ConnectionState::Connecting; // 释放旧连接(如果存在) if (m_pConnection) { delete m_pConnection; m_pConnection = nullptr; } // 设置全局超时参数 HINTERNET hSession = (HINTERNET)m_Session; // ✅ 正确获取 HINTERNET 句柄 if (hSession) { DWORD connectTimeout = 5000; // 5 秒 DWORD sendTimeout = m_GVariant.m_MesConfigFile->SendTimeout; DWORD recvTimeout = m_GVariant.m_MesConfigFile->RecvTimeout; InternetSetOption(hSession, INTERNET_OPTION_CONNECT_TIMEOUT, &connectTimeout, sizeof(connectTimeout)); InternetSetOption(hSession, INTERNET_OPTION_SEND_TIMEOUT, &sendTimeout, sizeof(sendTimeout)); InternetSetOption(hSession, INTERNET_OPTION_RECEIVE_TIMEOUT, &recvTimeout, sizeof(recvTimeout)); } try { // 创建新连接 m_pConnection = m_Session.GetHttpConnection( m_GFunction.String2CString(m_GVariant.m_MesConfigFile->Host), m_GVariant.m_MesConfigFile->Port, _T(""), // username _T("") // password ); if (m_pConnection) { m_connectionState = ConnectionState::Connected; // 更新缓存信息 m_cachedHost = m_GVariant.m_MesConfigFile->Host; m_cachedPort = m_GVariant.m_MesConfigFile->Port; CString logMsg; logMsg.Format(_T("MES连接成功: %s:%d"), m_GFunction.String2CString(m_cachedHost), m_cachedPort); addInfo(m_GFunction.CString2String(logMsg)); } else { m_connectionState = ConnectionState::Error; addErrInfo("MES连接失败: 无法创建HTTP连接"); } } catch (CInternetException* pEx) { TCHAR szError[1024]; pEx->GetErrorMessage(szError, 1024); m_connectionState = ConnectionState::Error; addErrInfo("MES连接异常: " + m_GFunction.CString2String(szError)); pEx->Delete(); } } Response MESInterface::Send(const string & info, const string & hostname, const int & port, const string & apiPath, string m_username, string m_password) { CriticalSectionLock lock(m_cs); // 检查连接状态 if (m_connectionState != ConnectionState::Connected) { Connect(); // 尝试重连 // 重连后仍然失败 if (m_connectionState != ConnectionState::Connected) { Response resp; resp.Code = NETWORK_ERROR; resp.Msg = "MES connection not established"; return resp; } } Response resp; if (!m_pConnection) { resp.Code = NETWORK_ERROR; resp.Msg = "Not connected to server. Call Connect() first."; return resp; } try { auto deleter = [](CHttpFile* p) { if (p) delete p; }; std::unique_ptr<CHttpFile, decltype(deleter)> pFile( m_pConnection->OpenRequest(CHttpConnection::HTTP_VERB_POST, m_GFunction.String2CString(apiPath)), deleter); // 设置请求头 CString strHeaders = _T("Content-Type: application/json\r\n"); strHeaders += _T("Authorization: Basic ") + EncodeBasicAuth(m_GFunction.String2CString(m_username), m_GFunction.String2CString(m_password)) + _T("\r\n"); // 转换请求数据 CString strData = m_GFunction.String2CString(info); pFile->SendRequest ( strHeaders, (DWORD)strHeaders.GetLength(), (LPVOID)(LPCTSTR)strData, (DWORD)strData.GetLength() ); DWORD dwStatusCode; pFile->QueryInfoStatusCode(dwStatusCode); CString strResponse; if (dwStatusCode == HTTP_STATUS_OK) { TCHAR szBuffer[1024]; while (pFile->Read(szBuffer, 1023) > 0) { strResponse += szBuffer; } } if (dwStatusCode != HTTP_STATUS_OK) { resp.Code = HTTP_ERROR; resp.Msg = QString::number(dwStatusCode); return resp; } resp.Msg = QString::fromLocal8Bit(m_GFunction.CString2String(strResponse).c_str()); pFile->Close(); } catch (CInternetException* pEx) { TCHAR szError[1024]; pEx->GetErrorMessage(szError, 1024); resp.Msg = QString::fromLocal8Bit(m_GFunction.CString2String(szError).c_str());// 异常信息写入resultMSG pEx->Delete(); resp.Code = NETWORK_ERROR; return resp; } resp.Code = SUCCESS; return resp; } // 添加连接状态查询方法(公共接口) ConnectionState MESInterface::GetConnectionState() const { return m_connectionState; } Response MESInterface::ParseRcv(string & msg) { QJsonDocument jsonDoc = QJsonDocument::fromJson(QByteArray::fromStdString(msg)); QJsonObject j = jsonDoc.object(); return Response::fromJson(j); } CString MESInterface::EncodeBasicAuth(const CString& username, const CString& password) { // 拼接用户名:密码 CString credentials = username + _T(":") + password; // 使用 Qt 转换宽字符 CString 到 QByteArray(UTF-8) QString qCredentials = QString::fromWCharArray(credentials.GetString()); QByteArray utf8Credentials = qCredentials.toUtf8(); // Base64 编码 QByteArray base64Data = utf8Credentials.toBase64(); // 将 Base64 数据转为 CString 返回 return CString(base64Data.constData()); } int MESInterface::checkFolder() { CriticalSectionLock lock(m_cs); // ✅ 加锁 m_currentFileNames.clear(); QString m_sourceFolder = QString::fromLocal8Bit(m_GVariant.m_MesConfigFile->Path_SourceTestFile.c_str()) + "\\MES" + QDateTime::currentDateTime().addDays(-1).toString("yyyyMMdd"); m_destinationFolder = QString::fromLocal8Bit(m_GVariant.m_MesConfigFile->Path_DestTestFile.c_str()) + "\\" + QDateTime::currentDateTime().addDays(-1).toString("yyyyMMdd"); bool result1 = m_File.moveAllFiles(m_sourceFolder, m_destinationFolder, m_currentFileNames); m_sourceFolder = QString::fromLocal8Bit(m_GVariant.m_MesConfigFile->Path_SourceTestFile.c_str()) + "\\MES" + QDateTime::currentDateTime().toString("yyyyMMdd"); m_destinationFolder = QString::fromLocal8Bit(m_GVariant.m_MesConfigFile->Path_DestTestFile.c_str()) + "\\" + QDateTime::currentDateTime().toString("yyyyMMdd"); bool result2 = m_File.moveAllFiles(m_sourceFolder, m_destinationFolder, m_currentFileNames); if (result1 || result2) { if (m_currentFileNames.size() > 0) { for (auto item : m_currentFileNames) { m_bufferFileNames.append(item); } return 1; } } else { return -1; } return 0; } 外部多线程调用这个类用来上传MES数据,过线检查和上传设备状态等事件,是否有啥问题
09-26
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值