Повреждение памяти(исключение read access violation 0x3e8.) после динамической загрузки в C++ с использованием VS2017
Приведенный ниже код прекрасно работает в VS2010 . Но это не работает в VS2017. Ниже фрагмент кода .
void ResultRule::ExecuteFireRule() { HINSTANCE hModule; CSiRuleReturn *pRuleRet = NULL; FIRERULE pFunc; hModule = LoadLibrary("siJCLJOb.dll"); pFunc = (FIRERULE) GetProcAddress(hModule, "FireRule"); if (pFunc != NULL) { try { pRuleRet = pFunc(inputList); } catch (CException *) { DeleteModuleInputList(inputList); throw; } DeleteModuleInputList(inputList); if (pRuleRet->GetReturnCode() > retVal.GetReturnCode()) { retVal.SetReturnCode(pRuleRet->GetReturnCode()); } if (pRuleRet->GetReturnObject()) { retVal.SetReturnObject(pRuleRet->GetReturnObject()); } retVal.AppendErrors(pRuleRet->GetErrorList()); delete pRuleRet; } else { CString msg; msg.Format("The result rule defined on line %d of %s referenced result module [%s], which has no exported FireRules function.", m_fileLineNumber, m_ruleFile, m_moduleName); CSiException *pEx = new CSiException("CSiResultRule::FireRule", msg); throw pEx; } }
------------------------------------------------------------------------------
Calling Above code: //Calling above ExecuteFireRule(), which will dynamically load firerule function of siJCLJOb.dll. CSiRuleReturn ruleRet = iRulesProcessor::GetInstance()->FireRequestRule("JCLCARD", NULL, ""); CString *pJobTemplate = (CString*)ruleRet.GetReturnObject(); // gives me the correct values after executing FireRule function of siJCLJob.dll CLauncherApp* Obj = (CLauncherApp*)AfxGetApp(); // after dynmic execution , it corrupts the memory /main thread . it show me the object siJCLJob.dll, when i place my cursor to Obj
Что я уже пробовал:
Мы сталкиваемся с одной и той же проблемой во всех динамических загруженных объектах MFC. Мы попытались скомпилировать код, добавив
/Zc:threadSafeInit... но получение ошибки во время выполнения
Exception thrown: read access violation. this was 0x3E8.
Rick York
Я предполагаю, что у вас есть проблема несоответствия версий с библиотеками DLL MFC. Попробуйте перестроить библиотеки DLL. Если вы не можете этого сделать, то вам, вероятно, нужно остаться с VS2010.
Member 13261094
Все MFC и DLL компилируются с использованием VS2017 в режиме отладки.
KarstenK
Рик прав, лучше всего построить все dll с одной и той же версией VS. Другой способ-сделать статическую сборку.
Shao Voon Wong
Проверьте, являются ли hModule и pFunc нулевыми. Проверка siJCLJOb.dll находится в исполняемом пути. Если они верны, то это может быть среда выполнения VC для siJCLJOb.dll не найден/не установлен. Попробуйте установить VS2010 runtime.
Member 13261094
Я отладил код, и он загружается в систему. siJCLJOB.dll и pFunc не является нулевым. После выполнения siJCLJOB.dll функция, она развращает основную память/поток.
Shao Voon Wong
Возможно, FireRule() и его указатель на функцию, объявление FIRERULE не совпадают? Пожалуйста, покажите 2 декларации.
Member 13261094
FireRule() работает нормально... Он выполняет код, написанный в SiJCLJob.dll и верните мне правильное значение в строке . но после этого код не работает ... он обнуляет основной поток.
siRuleReturn* FireRule(CObList& list)// в SiJCJoB
Shao Voon Wong
Объявление функции должно быть
siRuleReturn* по WinAPI FireRule(содержащий coblist&усилитель; список);
И объявление указателя функции должно быть
siRuleReturn* (WINAPI* FIRERULE)(CObList& list);
В прошлом я сталкивался с кодом, работавшим в более старом VC++, но разбившимся в более новом VC++. Оказывается, ошибка находится в нашем коде, потому что функция обратилась к элементу после конца вектора. Он не разбился в старом VC++, потому что в конце вектора нет ничего, что можно было бы испортить. Code-review код FireRule является правильным и не имеет доступа за пределы.