修复VrUtils单一初始化
This commit is contained in:
parent
4d9f7170ee
commit
3756a63a32
@ -148,7 +148,7 @@ win32:CONFIG(release, debug|release): {
|
|||||||
}
|
}
|
||||||
else:win32:CONFIG(debug, debug|release): {
|
else:win32:CONFIG(debug, debug|release): {
|
||||||
LIBS += -L$$PWD/../../../AppAlgo/particleSizeMeasure/Windows/x64/Debug -lparticleSizeMeasurement -lbaseAlgorithm
|
LIBS += -L$$PWD/../../../AppAlgo/particleSizeMeasure/Windows/x64/Debug -lparticleSizeMeasurement -lbaseAlgorithm
|
||||||
LIBS += -L$$PWD/../../../SDK/OpenCV320/Windows/vc14/Debug -lopencv_world320d
|
LIBS += -L$$PWD/../../../SDK/OpenCV320/Windows/vc14/Release -lopencv_world320
|
||||||
}
|
}
|
||||||
else:unix:!macx: {
|
else:unix:!macx: {
|
||||||
LIBS += -L$$PWD/../../../AppAlgo/particleSizeMeasure/Arm/aarch64 -lparticleSizeMeasurement -lbaseAlgorithm
|
LIBS += -L$$PWD/../../../AppAlgo/particleSizeMeasure/Arm/aarch64 -lparticleSizeMeasurement -lbaseAlgorithm
|
||||||
|
|||||||
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
#include <QCoreApplication>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
@ -24,6 +25,16 @@ WheelMeasurePresenter::WheelMeasurePresenter(QObject* parent)
|
|||||||
|
|
||||||
WheelMeasurePresenter::~WheelMeasurePresenter()
|
WheelMeasurePresenter::~WheelMeasurePresenter()
|
||||||
{
|
{
|
||||||
|
// 清除状态回调,防止后续回调访问已销毁对象
|
||||||
|
m_statusUpdate = nullptr;
|
||||||
|
|
||||||
|
// 停止顺序检测
|
||||||
|
m_stopSequentialRequested = true;
|
||||||
|
m_sequentialDetecting = false;
|
||||||
|
|
||||||
|
// 处理待处理的 Qt 事件,确保 QueuedConnection 的回调不会访问已销毁对象
|
||||||
|
QCoreApplication::processEvents();
|
||||||
|
|
||||||
if (m_config) {
|
if (m_config) {
|
||||||
delete m_config;
|
delete m_config;
|
||||||
m_config = nullptr;
|
m_config = nullptr;
|
||||||
|
|||||||
@ -41,9 +41,6 @@ win32:CONFIG(debug, debug|release) {
|
|||||||
LIBS += -L../../../AppUtils/AppCommon/debug -lAppCommon
|
LIBS += -L../../../AppUtils/AppCommon/debug -lAppCommon
|
||||||
LIBS += -L../../../Module/ModbusTCPServer/debug -lModbusTCPServer
|
LIBS += -L../../../Module/ModbusTCPServer/debug -lModbusTCPServer
|
||||||
LIBS += -L../../../VrNets/debug -lVrModbus
|
LIBS += -L../../../VrNets/debug -lVrModbus
|
||||||
|
|
||||||
# VzNLSDK
|
|
||||||
LIBS += -L../../../SDK/Device/VzNLSDK/Windows/x64/Debug -lVzKerneld
|
|
||||||
} else:win32:CONFIG(release, debug|release) {
|
} else:win32:CONFIG(release, debug|release) {
|
||||||
LIBS += -L../WheelMeasureConfig/release -lWheelMeasureConfig
|
LIBS += -L../WheelMeasureConfig/release -lWheelMeasureConfig
|
||||||
LIBS += -L../../../VrNets/release -lVrTcpClient
|
LIBS += -L../../../VrNets/release -lVrTcpClient
|
||||||
@ -54,9 +51,6 @@ win32:CONFIG(debug, debug|release) {
|
|||||||
LIBS += -L../../../AppUtils/AppCommon/release -lAppCommon
|
LIBS += -L../../../AppUtils/AppCommon/release -lAppCommon
|
||||||
LIBS += -L../../../Module/ModbusTCPServer/release -lModbusTCPServer
|
LIBS += -L../../../Module/ModbusTCPServer/release -lModbusTCPServer
|
||||||
LIBS += -L../../../VrNets/release -lVrModbus
|
LIBS += -L../../../VrNets/release -lVrModbus
|
||||||
|
|
||||||
# VzNLSDK
|
|
||||||
LIBS += -L../../../Device/VrEyeDevice/release -lVrEyeDevice
|
|
||||||
}else:unix:!macx {
|
}else:unix:!macx {
|
||||||
# 注意:静态库链接顺序很重要,被依赖的库必须放在后面
|
# 注意:静态库链接顺序很重要,被依赖的库必须放在后面
|
||||||
LIBS += -L../WheelMeasureConfig -lWheelMeasureConfig
|
LIBS += -L../WheelMeasureConfig -lWheelMeasureConfig
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
#include <QCoreApplication>
|
||||||
#include "PathManager.h"
|
#include "PathManager.h"
|
||||||
#include "IYModbusTCPServer.h"
|
#include "IYModbusTCPServer.h"
|
||||||
|
|
||||||
@ -22,11 +23,17 @@ BasePresenter::BasePresenter(QObject *parent)
|
|||||||
|
|
||||||
BasePresenter::~BasePresenter()
|
BasePresenter::~BasePresenter()
|
||||||
{
|
{
|
||||||
|
// 清除状态回调指针,防止后续回调访问
|
||||||
|
m_pStatusCallback = nullptr;
|
||||||
|
|
||||||
// 等待初始化线程完成
|
// 等待初始化线程完成
|
||||||
if (m_initThread.joinable()) {
|
if (m_initThread.joinable()) {
|
||||||
m_initThread.join();
|
m_initThread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理待处理的 Qt 事件,确保 QueuedConnection 的回调执行时检查到 m_pStatusCallback 为空
|
||||||
|
QCoreApplication::processEvents();
|
||||||
|
|
||||||
// 停止检测线程
|
// 停止检测线程
|
||||||
StopAlgoDetectThread();
|
StopAlgoDetectThread();
|
||||||
|
|
||||||
|
|||||||
@ -4,6 +4,8 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <clocale>
|
#include <clocale>
|
||||||
|
#include <mutex>
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
#include <log4cpp/Category.hh>
|
#include <log4cpp/Category.hh>
|
||||||
#include <log4cpp/Appender.hh>
|
#include <log4cpp/Appender.hh>
|
||||||
@ -41,10 +43,29 @@
|
|||||||
#define LOG_CONFIG_FILE "config.ini"
|
#define LOG_CONFIG_FILE "config.ini"
|
||||||
#define LOG_PRINT_FILE "AppLog.log"
|
#define LOG_PRINT_FILE "AppLog.log"
|
||||||
|
|
||||||
static log4cpp::PatternLayout* m_pLayout = nullptr;
|
// 使用函数内静态变量实现真正的全局单例(跨静态库安全)
|
||||||
static log4cpp::RollingFileAppender* m_prollfileAppender = nullptr;
|
struct VrLogState {
|
||||||
static bool g_isLogInitialized = false;
|
log4cpp::PatternLayout* pLayout = nullptr;
|
||||||
static bool g_isTimeEnabled = true;
|
log4cpp::RollingFileAppender* pRollFileAppender = nullptr;
|
||||||
|
std::atomic<bool> isInitialized{false};
|
||||||
|
std::atomic<bool> isShutdown{false}; // 标记日志系统是否已关闭(程序退出时)
|
||||||
|
std::atomic<bool> isTimeEnabled{true};
|
||||||
|
std::once_flag initFlag;
|
||||||
|
std::once_flag uninitFlag;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 函数内静态变量,确保跨编译单元的唯一性
|
||||||
|
static VrLogState& GetLogState() {
|
||||||
|
static VrLogState state;
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 兼容旧代码的访问方式
|
||||||
|
#define m_pLayout (GetLogState().pLayout)
|
||||||
|
#define m_prollfileAppender (GetLogState().pRollFileAppender)
|
||||||
|
#define g_isLogInitialized (GetLogState().isInitialized)
|
||||||
|
#define g_isLogShutdown (GetLogState().isShutdown)
|
||||||
|
#define g_isTimeEnabled (GetLogState().isTimeEnabled)
|
||||||
|
|
||||||
|
|
||||||
#ifdef STM32_UCOSIII
|
#ifdef STM32_UCOSIII
|
||||||
@ -165,14 +186,9 @@ public:
|
|||||||
// 静态实例,程序启动时自动初始化日志,程序退出时自动清理日志
|
// 静态实例,程序启动时自动初始化日志,程序退出时自动清理日志
|
||||||
static VrLogAutoCleaner g_logAutoCleaner;
|
static VrLogAutoCleaner g_logAutoCleaner;
|
||||||
|
|
||||||
/// 初始化log
|
// 实际执行初始化的内部函数
|
||||||
void VrLogUtils::InitLog()
|
static void DoInitLog()
|
||||||
{
|
{
|
||||||
// 防止重复初始化
|
|
||||||
if (g_isLogInitialized) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
// 设置控制台代码页为 UTF-8,解决中文乱码
|
// 设置控制台代码页为 UTF-8,解决中文乱码
|
||||||
SetConsoleOutputCP(CP_UTF8);
|
SetConsoleOutputCP(CP_UTF8);
|
||||||
@ -204,25 +220,26 @@ void VrLogUtils::InitLog()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create file appender
|
// create file appender
|
||||||
if (nullptr == m_pLayout)
|
VrLogState& state = GetLogState();
|
||||||
|
if (nullptr == state.pLayout)
|
||||||
{
|
{
|
||||||
m_pLayout = new log4cpp::PatternLayout;
|
state.pLayout = new log4cpp::PatternLayout;
|
||||||
// 设置布局格式,可以控制是否自动换行
|
// 设置布局格式,可以控制是否自动换行
|
||||||
// %d{%Y-%m-%d %H:%M:%S.%l} [%p] %c - %m%n
|
// %d{%Y-%m-%d %H:%M:%S.%l} [%p] %c - %m%n
|
||||||
// 其中 %n 表示换行符,如果想要控制换行可以去掉或修改这个
|
// 其中 %n 表示换行符,如果想要控制换行可以去掉或修改这个
|
||||||
m_pLayout->setConversionPattern("%d{%Y-%m-%d %H:%M:%S.%l} [%p] %m");
|
state.pLayout->setConversionPattern("%d{%Y-%m-%d %H:%M:%S.%l} [%p] %m");
|
||||||
}
|
}
|
||||||
if (nullptr == m_prollfileAppender)
|
if (nullptr == state.pRollFileAppender)
|
||||||
{
|
{
|
||||||
m_prollfileAppender = new log4cpp::RollingFileAppender("AppLogAppender", logPath + PATH_SEP + LOG_PRINT_FILE,
|
state.pRollFileAppender = new log4cpp::RollingFileAppender("AppLogAppender", logPath + PATH_SEP + LOG_PRINT_FILE,
|
||||||
1024 * 1024, // 单个文件大小1M
|
1024 * 1024, // 单个文件大小1M
|
||||||
10); // 10个文件
|
10); // 10个文件
|
||||||
|
|
||||||
m_prollfileAppender->setLayout(m_pLayout);
|
state.pRollFileAppender->setLayout(state.pLayout);
|
||||||
|
|
||||||
// add appender to category
|
// add appender to category
|
||||||
log4cpp::Category& root = log4cpp::Category::getRoot();
|
log4cpp::Category& root = log4cpp::Category::getRoot();
|
||||||
root.addAppender(m_prollfileAppender);
|
root.addAppender(state.pRollFileAppender);
|
||||||
|
|
||||||
// set priority
|
// set priority
|
||||||
root.setPriority(log4cpp::Priority::DEBUG);
|
root.setPriority(log4cpp::Priority::DEBUG);
|
||||||
@ -232,27 +249,41 @@ void VrLogUtils::InitLog()
|
|||||||
g_isLogInitialized = true;
|
g_isLogInitialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 关闭log
|
/// 初始化log
|
||||||
void VrLogUtils::UninitLog()
|
void VrLogUtils::InitLog()
|
||||||
{
|
{
|
||||||
if (!g_isLogInitialized) {
|
// 如果已经关闭,不再初始化
|
||||||
|
if (g_isLogShutdown) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_pLayout)
|
// 使用 call_once 确保只执行一次初始化(跨静态库安全)
|
||||||
{
|
std::call_once(GetLogState().initFlag, DoInitLog);
|
||||||
delete m_pLayout;
|
|
||||||
m_pLayout = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_prollfileAppender)
|
// 实际执行清理的内部函数
|
||||||
|
static void DoUninitLog()
|
||||||
{
|
{
|
||||||
delete m_prollfileAppender;
|
// 先设置标志,防止其他线程继续调用日志
|
||||||
m_prollfileAppender = nullptr;
|
|
||||||
}
|
|
||||||
log4cpp::Category::shutdown();//关闭Category;
|
|
||||||
|
|
||||||
g_isLogInitialized = false;
|
g_isLogInitialized = false;
|
||||||
|
g_isLogShutdown = true; // 标记已关闭,防止 EchoLog 重新初始化
|
||||||
|
|
||||||
|
// 注意:不调用 log4cpp::Category::shutdown()
|
||||||
|
// 原因:静态对象析构顺序不确定,log4cpp 内部的静态对象可能在
|
||||||
|
// VrLogAutoCleaner 之前就已经被析构,此时调用 shutdown() 会崩溃。
|
||||||
|
// 程序退出时,操作系统会自动回收所有内存,不需要手动清理。
|
||||||
|
|
||||||
|
// 只置空指针,不删除对象(对象由 log4cpp 内部管理)
|
||||||
|
VrLogState& state = GetLogState();
|
||||||
|
state.pLayout = nullptr;
|
||||||
|
state.pRollFileAppender = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 关闭log
|
||||||
|
void VrLogUtils::UninitLog()
|
||||||
|
{
|
||||||
|
// 使用 call_once 确保只执行一次清理(跨静态库安全)
|
||||||
|
std::call_once(GetLogState().uninitFlag, DoUninitLog);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -269,6 +300,11 @@ void VrLogUtils::EnableTime(bool bEnable)
|
|||||||
/// 输出log
|
/// 输出log
|
||||||
void VrLogUtils::EchoLog(VrLogLevel eLogLevel, const char* sFilePath, const int nLine, const char* sLogGroup, const char* sFormat, ...)
|
void VrLogUtils::EchoLog(VrLogLevel eLogLevel, const char* sFilePath, const int nLine, const char* sLogGroup, const char* sFormat, ...)
|
||||||
{
|
{
|
||||||
|
// 如果日志系统已关闭(程序退出),直接返回,不要重新初始化
|
||||||
|
if (g_isLogShutdown) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 由于VrLogAutoCleaner会在程序启动时自动初始化,这里只做保险检查
|
// 由于VrLogAutoCleaner会在程序启动时自动初始化,这里只做保险检查
|
||||||
if (!g_isLogInitialized) {
|
if (!g_isLogInitialized) {
|
||||||
InitLog();
|
InitLog();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user