Как простое сравнение строк может вызвать OleException? - PullRequest
0 голосов
/ 13 февраля 2019

У меня есть этот фрагмент кода C ++:

static CString timeout(_T("TIMEOUT"));
if(strError.Left(7).CompareNoCase(timeout) == 0) return TRUE;

В моих непосредственных окнах я вижу следующее значение для strError:

? strError
L""
ATL::CSimpleStringT<wchar_t,1>: L""

Я получаю следующее исключение (Я отлаживаю аварийный дамп):

Unhandled exception at 0x74B4A9F2 in CRASH.DMP: Microsoft C++ exception: 
COleException at memory location 0x01BFFD14. occurred

Мой стек вызовов выглядит следующим образом:

   KERNELBASE.dll!_RaiseException@16()  Unknown
   msvcr110.dll!_CxxThrowException(void * pExceptionObject, const _s__ThrowInfo * pThrowInfo) Line 152  C++
   mfc110u.dll!AfxThrowOleException(long)   Unknown
   mfc110u.dll!ATL::AtlThrowImpl(long)  Unknown
   mfc110u.dll!ATL::CStringT<wchar_t,class StrTraitMFC_DLL<wchar_t,class ATL::ChTraitsCRT<wchar_t> > >::CompareNoCase(wchar_t const *)  Unknown
>  <Application>.exe!<Own_Class>::<Own_Function>(const ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > > & strError) Line 106 C++

Поскольку у меня был сбой при проверке .Left(7) пустой строки,Я сразу предположил, что это был ход вопроса.Однако я понял, что этот кусок кода, как правило, работает нормально (я просто дважды проверил это), и, хотя я посмотрел второй раз, я вижу, что это исключение, если не нарушение прав доступа или исключение нулевого значения, а исключение, связанное с Ole.Тем временем я понял, что проблема не в части strError.Left(7): похоже, что метод CompareNoCase() идет не так, но как?

Может кто-нибудь просветить меня, что не так в моем коде?

Что касается strError, то он создается следующим образом:

CString strError;
...
strError = <function>();

, где <function>() - это что-то вроде:

CString <function>(){
...
  return _T("fix string"); // or:
  return <Complicated_function_handling>();

В этомВ конкретном случае я понятия не имею, как был создан strError (я знаю, что он пуст, как ясно видно в ближайшем окне, но у меня есть только аварийный дамп, поэтому я могу читать текущие значения, но я не знаю ихистория).

Одна вещь, которая может оказаться полезной: я попросил адрес памяти strError, и я посмотрел на данные в памяти (используя окно отладки памяти Visual Studio), иЯ получаю следующие данные:

5c 18 9c 71 38 d9 ca 00 03 00 00 00 cc 3d c2 00 70 fe bf 01 94 13 b3 00 39 00 00 00 80 fe bf 01 be 58 aa 00 b0 3d c2 00 10 0c cd 00 44 03 00 00 01 00 00 00 d3 5f ac 00 8a 40 1d 72 8e f2 d6 73

Заранее спасибо

1 Ответ

0 голосов
/ 20 февраля 2019

При работе через источник для MFC создается исключение, потому что timeOut является пустой строкой.Обычные способы, которыми это может произойти, - это если он еще не построен или был разрушен.Код ошибки, сохраненный в COleException, равен E_FAIL.

. Последовательность вызовов выглядит примерно так:

  • CompareNoCase вызовов AtlIsValidString (которая возвращает false вваш случай, если timeOut при преобразовании в const char * равен NULL).
  • Поскольку AtlIsValidString возвращает значение false, код, связанный с макро вызовами ATLENSURE AtlThrow(E_FAIL) (AtlThrowмакрос, который определяется как ATL::AtlThrowImpl.
  • AtlThrowImpl, вызывает AfxThrowOleException, поскольку код ошибки не E_OUTOFMEMORY.
...