diff --git a/Src/nmNum/nmCalculation/nmCalculationAutoFitLM.cpp b/Src/nmNum/nmCalculation/nmCalculationAutoFitLM.cpp index 8422c13..48f40da 100644 --- a/Src/nmNum/nmCalculation/nmCalculationAutoFitLM.cpp +++ b/Src/nmNum/nmCalculation/nmCalculationAutoFitLM.cpp @@ -26,11 +26,7 @@ #define DEBUG_OUT(msg) OutputDebugStringA(QString("[AutoFitLM] %1\n").arg(msg).toLocal8Bit().data()) #endif -#ifdef QT_NO_DEBUG -static const bool kAutoFitDiagnosticTraceEnabled = false; -#else static const bool kAutoFitDiagnosticTraceEnabled = true; -#endif static inline bool isFiniteNumber(double value) { @@ -687,7 +683,7 @@ void nmCalculationAutoFitLM::initializeTraceFile() return; } - // 诊断轨迹仅在 Debug 构建中启用,并与源码、安装目录完全分离。 + // 诊断轨迹在所有构建中启用,并与源码、安装目录完全分离。 if(m_traceRunId.isEmpty()) { m_traceRunId = QString("%1-%2") .arg(QString::number(QCoreApplication::applicationPid())) diff --git a/Src/nmNum/nmCalculation/nmCalculationPebiGrid.cpp b/Src/nmNum/nmCalculation/nmCalculationPebiGrid.cpp index added2b..7b50c22 100644 --- a/Src/nmNum/nmCalculation/nmCalculationPebiGrid.cpp +++ b/Src/nmNum/nmCalculation/nmCalculationPebiGrid.cpp @@ -36,6 +36,36 @@ namespace { const int CONST_PVT_POINT_COUNT = 200; +typedef void (*HX_NWTM_GRID_Func)( + HX_NWTM_GRID_OUTPUT1&, + HX_NWTM_GRID_OUTPUT2&, + const HX_NWTM_GRID_INPUT&, + std::string); + +__declspec(noinline) void invokePebiGridDll( + HX_NWTM_GRID_Func pfnGenerateGrid, + const nmPebiGridInputSnapshot& oSnapshot, + nmPebiGridResult& oResult) +{ + // 单独调用网格 DLL,避免字符串参数的构造、析构与异常捕获放在同一函数中导致编译错误。 + pfnGenerateGrid(oResult.m_oGridOutput1, oResult.m_oGridOutput2, + oSnapshot.m_oGridInput, oSnapshot.m_sLicensePath.toStdString()); +} + +bool invokePebiGridDllGuarded(HX_NWTM_GRID_Func pfnGenerateGrid, + const nmPebiGridInputSnapshot& oSnapshot, + nmPebiGridResult& oResult) +{ + // 仅拦截已复现的访问违例;普通 C++ 异常继续交给外层 catch,堆损坏不在此恢复。 + __try { + invokePebiGridDll(pfnGenerateGrid, oSnapshot, oResult); + } __except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION + ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { + return false; + } + return true; +} + // 该锁只保护 PEBI 网格单例缓存;HX_NWTM.dll 的所有入口由独立进程级锁保护。 // 保留递归锁以兼容可能在持锁网格入口中调用缓存查询的旧代码路径。 QMutex s_oPebiGridMutex(QMutex::Recursive); @@ -1660,11 +1690,6 @@ bool nmCalculationPebiGrid::calculateSnapshot( return false; } - typedef void (*HX_NWTM_GRID_Func)( - HX_NWTM_GRID_OUTPUT1&, - HX_NWTM_GRID_OUTPUT2&, - const HX_NWTM_GRID_INPUT&, - std::string); typedef int (*GetIntValueFunc)(); HX_NWTM_GRID_Func pfnGenerateGrid = @@ -1687,10 +1712,13 @@ bool nmCalculationPebiGrid::calculateSnapshot( } // 第二步:DLL 输出先落在局部结果,失败时不清空单例缓存和已有成果。 - pfnGenerateGrid(oResult.m_oGridOutput1, - oResult.m_oGridOutput2, - oSnapshot.m_oGridInput, - oSnapshot.m_sLicensePath.toStdString()); + if(!invokePebiGridDllGuarded(pfnGenerateGrid, oSnapshot, oResult)) { + // 本轮结果不再用于显示或求解,沿用现有失败通知保留旧成果。 + nmCalculationUtils::cleanupPebiGridDebugFiles(); + FreeLibrary(hGridModule); + hGridModule = nullptr; + return false; + } nmCalculationUtils::cleanupPebiGridDebugFiles(); oResult.m_nPebiCount = pfnGetPebiCount();